forked from 1b-agent/opencadstudio-upstream
Merge pull request #893 from ramox81/codex/complete-baseline-dimension
Complete DIMBASELINE workflow and creation policy
This commit is contained in:
20 files changed
+1198
-427
No files matched your search
+36
-88
@@ -646,36 +646,50 @@ impl OpenCADStudio {
|
||||
|
||||
"DIMCONTINUE" => {
|
||||
use crate::modules::annotate::dim_continue::DimContinueCommand;
|
||||
let cmd = if let Some((p1, p2, dp, rot, trot)) =
|
||||
find_last_linear_dim(&self.tabs[i].scene)
|
||||
{
|
||||
DimContinueCommand::from_base(p1, p2, dp, rot, trot)
|
||||
} else {
|
||||
DimContinueCommand::new()
|
||||
};
|
||||
let scene = &self.tabs[i].scene;
|
||||
let preserve_base_style = self.dimension_continue_mode == 1;
|
||||
let cmd = scene
|
||||
.last_created_dimension
|
||||
.filter(|handle| scene.entity_belongs_to_active_space(*handle))
|
||||
.and_then(|handle| scene.document.get_entity(handle))
|
||||
.and_then(|entity| match entity {
|
||||
acadrust::EntityType::Dimension(dimension) => Some(
|
||||
DimContinueCommand::from_dimension(dimension, preserve_base_style),
|
||||
),
|
||||
_ => None,
|
||||
})
|
||||
.unwrap_or_else(|| DimContinueCommand::new(preserve_base_style));
|
||||
self.command_line.push_info(&cmd.prompt());
|
||||
self.tabs[i].active_cmd = Some(Box::new(cmd));
|
||||
}
|
||||
|
||||
"DIMBASELINE" => {
|
||||
use crate::modules::annotate::dim_baseline::DimBaselineCommand;
|
||||
let cmd = if let Some((p1, p2, dp, rot, trot)) =
|
||||
find_last_linear_dim(&self.tabs[i].scene)
|
||||
{
|
||||
let doc = &self.tabs[i].scene.document;
|
||||
let dimdli = doc
|
||||
.dim_styles
|
||||
.iter()
|
||||
.find(|s| {
|
||||
s.name
|
||||
.eq_ignore_ascii_case(&doc.header.current_dimstyle_name)
|
||||
})
|
||||
.map(|s| s.dimdli as f32)
|
||||
.unwrap_or(1.5);
|
||||
DimBaselineCommand::from_base(p1, p2, dp, rot, trot, dimdli)
|
||||
let scene = &self.tabs[i].scene;
|
||||
let recent = scene
|
||||
.last_created_dimension
|
||||
.filter(|handle| scene.entity_belongs_to_active_space(*handle))
|
||||
.and_then(|handle| scene.document.get_entity(handle))
|
||||
.cloned();
|
||||
let dimdli_by_style = scene
|
||||
.document
|
||||
.dim_styles
|
||||
.iter()
|
||||
.map(|style| (style.name.to_ascii_lowercase(), style.dimdli))
|
||||
.collect();
|
||||
let fallback_dimdli = if scene.document.header.measurement == 1 {
|
||||
3.75
|
||||
} else {
|
||||
DimBaselineCommand::new()
|
||||
0.38
|
||||
};
|
||||
let current_style_name = scene.document.header.current_dimstyle_name.clone();
|
||||
let cmd = DimBaselineCommand::new(
|
||||
recent,
|
||||
dimdli_by_style,
|
||||
current_style_name,
|
||||
fallback_dimdli,
|
||||
self.dimension_continue_mode == 1,
|
||||
);
|
||||
self.command_line.push_info(&cmd.prompt());
|
||||
self.tabs[i].active_cmd = Some(Box::new(cmd));
|
||||
}
|
||||
@@ -1376,72 +1390,6 @@ impl OpenCADStudio {
|
||||
}
|
||||
}
|
||||
|
||||
/// Find the last placed linear or aligned dimension in the document.
|
||||
/// Returns `(first_point, second_point, definition_point, rotation_rad)` in world-space.
|
||||
fn find_last_linear_dim(
|
||||
scene: &crate::scene::Scene,
|
||||
) -> Option<(glam::Vec3, glam::Vec3, glam::Vec3, f64, f64)> {
|
||||
use acadrust::entities::Dimension;
|
||||
let mut best_handle: u64 = 0;
|
||||
let mut result: Option<(glam::Vec3, glam::Vec3, glam::Vec3, f64, f64)> = None;
|
||||
|
||||
for entity in scene.document.entities() {
|
||||
if let acadrust::EntityType::Dimension(dim) = entity {
|
||||
let h = entity.common().handle.value();
|
||||
if h <= best_handle {
|
||||
continue;
|
||||
}
|
||||
let item = match dim {
|
||||
Dimension::Linear(d) => {
|
||||
let p1 = glam::Vec3::new(
|
||||
d.first_point.x as f32,
|
||||
d.first_point.y as f32,
|
||||
d.first_point.z as f32,
|
||||
);
|
||||
let p2 = glam::Vec3::new(
|
||||
d.second_point.x as f32,
|
||||
d.second_point.y as f32,
|
||||
d.second_point.z as f32,
|
||||
);
|
||||
let dp = glam::Vec3::new(
|
||||
d.base.definition_point.x as f32,
|
||||
d.base.definition_point.y as f32,
|
||||
d.base.definition_point.z as f32,
|
||||
);
|
||||
Some((p1, p2, dp, d.rotation, d.base.text_rotation))
|
||||
}
|
||||
Dimension::Aligned(d) => {
|
||||
let p1 = glam::Vec3::new(
|
||||
d.first_point.x as f32,
|
||||
d.first_point.y as f32,
|
||||
d.first_point.z as f32,
|
||||
);
|
||||
let p2 = glam::Vec3::new(
|
||||
d.second_point.x as f32,
|
||||
d.second_point.y as f32,
|
||||
d.second_point.z as f32,
|
||||
);
|
||||
let dp = glam::Vec3::new(
|
||||
d.base.definition_point.x as f32,
|
||||
d.base.definition_point.y as f32,
|
||||
d.base.definition_point.z as f32,
|
||||
);
|
||||
let dx = (d.second_point.x - d.first_point.x) as f32;
|
||||
let dy = (d.second_point.y - d.first_point.y) as f32;
|
||||
let rot = dy.atan2(dx) as f64;
|
||||
Some((p1, p2, dp, rot, d.base.text_rotation))
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
if let Some(data) = item {
|
||||
best_handle = h;
|
||||
result = Some(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
/// Collect candidate dimension endpoints from an entity for QDIM — line ends,
|
||||
/// polyline vertices, arc endpoints — in world space.
|
||||
fn qdim_collect_points(e: &acadrust::EntityType, out: &mut Vec<glam::DVec3>) {
|
||||
|
||||
@@ -931,6 +931,7 @@ impl OpenCADStudio {
|
||||
| "CENTERCROSSSIZE"
|
||||
| "CENTERCROSSGAP"
|
||||
| "CENTERMARKEXE"
|
||||
| "DIMCONTINUEMODE"
|
||||
) =>
|
||||
{
|
||||
return self.dispatch_styleprops(&format!("SETVAR {cmd}"), i);
|
||||
@@ -953,7 +954,7 @@ impl OpenCADStudio {
|
||||
let value = it.next().map(|s| s.trim().to_string());
|
||||
if name.is_empty() || name == "?" {
|
||||
self.command_line.push_info(
|
||||
"SETVAR: LTSCALE CELTSCALE PDMODE PDSIZE TEXTSIZE ORTHOMODE FILLMODE MIRRTEXT FRAME IMAGEFRAME PDFFRAME WIPEOUTFRAME XCLIPFRAME POINTCLOUDCLIPFRAME ZOOMWHEEL ZOOMFACTOR CURSORSIZE PICKBOX CURSORTYPE SNAPANG TEXTFILL CLIPROMPTLINES ATTREQ ATTDIA DIMASSOC ANGBASE ANGDIR SKETCHINC SKPOLY SKTOLERANCE DONUTID DONUTOD CENTEREXE CENTERLAYER CENTERLTYPE CENTERLTSCALE CENTERLTYPEFILE CENTERCROSSSIZE CENTERCROSSGAP CENTERMARKEXE | CLAYER CELTYPE TEXTSTYLE (read-only)",
|
||||
"SETVAR: LTSCALE CELTSCALE PDMODE PDSIZE TEXTSIZE ORTHOMODE FILLMODE MIRRTEXT FRAME IMAGEFRAME PDFFRAME WIPEOUTFRAME XCLIPFRAME POINTCLOUDCLIPFRAME ZOOMWHEEL ZOOMFACTOR CURSORSIZE PICKBOX CURSORTYPE SNAPANG TEXTFILL CLIPROMPTLINES ATTREQ ATTDIA DIMASSOC DIMCONTINUEMODE ANGBASE ANGDIR SKETCHINC SKPOLY SKTOLERANCE DONUTID DONUTOD CENTEREXE CENTERLAYER CENTERLTYPE CENTERLTSCALE CENTERLTYPEFILE CENTERCROSSSIZE CENTERCROSSGAP CENTERMARKEXE | CLAYER CELTYPE TEXTSTYLE (read-only)",
|
||||
);
|
||||
} else {
|
||||
let frame_kind = crate::scene::frame::kind_for_name(&name);
|
||||
@@ -1069,6 +1070,28 @@ impl OpenCADStudio {
|
||||
}
|
||||
return Some(self.finish_dispatch(cmd));
|
||||
}
|
||||
if name == "DIMCONTINUEMODE" {
|
||||
let current = self.dimension_continue_mode;
|
||||
if let Some(value) = &value {
|
||||
match value.parse::<i16>() {
|
||||
Ok(mode @ 0..=1) => {
|
||||
self.dimension_continue_mode = mode;
|
||||
self.persist_settings_if_changed();
|
||||
self.command_line
|
||||
.push_output(&format!("DIMCONTINUEMODE = {mode}"));
|
||||
}
|
||||
_ => self.command_line.push_error(
|
||||
"SETVAR: DIMCONTINUEMODE requires 0 or 1.",
|
||||
),
|
||||
}
|
||||
} else {
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"Enter new value for {name} <{current}>:"
|
||||
).as_ref());
|
||||
self.pending_setvar = Some(name.clone());
|
||||
}
|
||||
return Some(self.finish_dispatch(cmd));
|
||||
}
|
||||
if matches!(name.as_str(), "DONUTID" | "DONUTOD") {
|
||||
let current = if name == "DONUTID" {
|
||||
crate::modules::draw::defaults::get_donut_inner_diameter()
|
||||
|
||||
Reference in new issue
Block a user