Merge pull request #850 from ramox81/codex/associative-center-mark

This commit is contained in:
Hakan Seven committed 2026-08-21 20:19:54 +03:00
commit b648000e78
21 files changed
+1672 -241

No files matched your search

+20
View File
@@ -1495,6 +1495,26 @@ impl OpenCADStudio {
}
self.refresh_properties();
}
CmdResult::ReassociateCenterMark { target, source, point } => {
if self.reject_locked_edit(i, target) {
return Task::none();
}
self.push_undo_snapshot(i, "CENTERREASSOCIATE");
if self.tabs[i].scene.reassociate_center_mark(target, source, point) {
self.tabs[i].dirty = true;
self.command_line.push_output(
"CENTERREASSOCIATE: center mark associated.",
);
} else {
self.command_line.push_error(
"CENTERREASSOCIATE: the selected source is not circular.",
);
}
self.tabs[i].active_cmd = None;
self.tabs[i].snap_result = None;
self.tabs[i].scene.clear_preview_wire();
self.refresh_properties();
}
CmdResult::ReplaceEntity(handle, new_entities) => {
if self.reject_locked_edit(i, handle) {
return Task::none();
+58 -2
View File
@@ -473,18 +473,74 @@ impl OpenCADStudio {
"CENTERLINE" => {
use crate::modules::draw::draw::centerline::CenterLineCommand;
let new_cmd = CenterLineCommand::new();
let settings = self.tabs[i].scene.centerline_settings();
let new_cmd = CenterLineCommand::new(settings);
self.command_line.push_info(&new_cmd.prompt());
self.tabs[i].active_cmd = Some(Box::new(new_cmd));
}
"DIMCENTER" | "CENTERMARK" => {
"CENTERRESET" => {
let handles = self.tabs[i].scene.selected_handles_in_order();
self.push_undo_snapshot(i, "CENTERRESET");
let count = self.tabs[i].scene.reset_centerlines(&handles)
+ self.tabs[i].scene.reset_center_marks(&handles);
if count > 0 {
self.tabs[i].dirty = true;
}
self.command_line
.push_output(&format!("CENTERRESET: {count} center object(s) updated."));
}
"CENTERREASSOCIATE" => {
let handles = self.tabs[i].scene.selected_handles_in_order();
let mark_targets: Vec<_> = handles.iter().copied().filter(|handle| {
let Some(acadrust::EntityType::Line(line)) = self.tabs[i].scene.document.get_entity(*handle) else { return false; };
acadrust::entities::CenterMarkAssociation::read(&line.common.extended_data).is_some()
}).collect();
if mark_targets.len() == 1 && handles.len() == 1 {
use crate::modules::draw::draw::dimcenter::CenterMarkReassociateCommand;
let new_cmd = CenterMarkReassociateCommand::new(mark_targets[0]);
self.command_line.push_info(&new_cmd.prompt());
self.tabs[i].active_cmd = Some(Box::new(new_cmd));
return Some(self.finish_dispatch(cmd));
}
self.push_undo_snapshot(i, "CENTERREASSOCIATE");
let count = self.tabs[i].scene.set_centerline_association(&handles, true)
+ self.tabs[i].scene.set_center_mark_association(&handles, true);
if count > 0 {
self.tabs[i].dirty = true;
}
self.command_line
.push_output(&format!("CENTERREASSOCIATE: {count} center object(s) associated."));
}
"CENTERDISASSOCIATE" => {
let handles = self.tabs[i].scene.selected_handles_in_order();
self.push_undo_snapshot(i, "CENTERDISASSOCIATE");
let count = self.tabs[i].scene.set_centerline_association(&handles, false)
+ self.tabs[i].scene.set_center_mark_association(&handles, false);
if count > 0 {
self.tabs[i].dirty = true;
}
self.command_line
.push_output(&format!("CENTERDISASSOCIATE: {count} center object(s) detached."));
}
"DIMCENTER" => {
use crate::modules::draw::draw::dimcenter::DimCenterCommand;
let new_cmd = DimCenterCommand::new();
self.command_line.push_info(&new_cmd.prompt());
self.tabs[i].active_cmd = Some(Box::new(new_cmd));
}
"CENTERMARK" => {
use crate::modules::draw::draw::dimcenter::CenterMarkCommand;
let settings = self.tabs[i].scene.centerline_settings();
let new_cmd = CenterMarkCommand::new(settings);
self.command_line.push_info(&new_cmd.prompt());
self.tabs[i].active_cmd = Some(Box::new(new_cmd));
}
"SKETCH" => {
use crate::modules::draw::draw::sketch::SketchCommand;
let header = &self.tabs[i].scene.document.header;
+48 -1
View File
@@ -933,6 +933,14 @@ impl OpenCADStudio {
| "SKETCHINC"
| "SKPOLY"
| "SKTOLERANCE"
| "CENTEREXE"
| "CENTERLAYER"
| "CENTERLTYPE"
| "CENTERLTSCALE"
| "CENTERLTYPEFILE"
| "CENTERCROSSSIZE"
| "CENTERCROSSGAP"
| "CENTERMARKEXE"
) =>
{
return self.dispatch_styleprops(&format!("SETVAR {cmd}"), i);
@@ -955,7 +963,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 ATTREQ ATTDIA DIMASSOC ANGBASE ANGDIR SKETCHINC SKPOLY SKTOLERANCE | 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 ATTREQ ATTDIA DIMASSOC ANGBASE ANGDIR SKETCHINC SKPOLY SKTOLERANCE CENTEREXE CENTERLAYER CENTERLTYPE CENTERLTSCALE CENTERLTYPEFILE CENTERCROSSSIZE CENTERCROSSGAP CENTERMARKEXE | CLAYER CELTYPE TEXTSTYLE (read-only)",
);
} else {
let frame_kind = crate::scene::frame::kind_for_name(&name);
@@ -1032,6 +1040,45 @@ impl OpenCADStudio {
}
return Some(self.finish_dispatch(cmd));
}
if matches!(
name.as_str(),
"CENTEREXE"
| "CENTERLAYER"
| "CENTERLTYPE"
| "CENTERLTSCALE"
| "CENTERLTYPEFILE"
| "CENTERCROSSSIZE"
| "CENTERCROSSGAP"
| "CENTERMARKEXE"
) {
let settings = self.tabs[i].scene.centerline_settings();
let current = match name.as_str() {
"CENTEREXE" => settings.extension.to_string(),
"CENTERLAYER" => settings.layer,
"CENTERLTYPE" => settings.linetype,
"CENTERLTSCALE" => settings.linetype_scale.to_string(),
"CENTERLTYPEFILE" => settings.linetype_file,
"CENTERCROSSSIZE" => settings.cross_size,
"CENTERCROSSGAP" => settings.cross_gap,
"CENTERMARKEXE" => i16::from(settings.mark_extensions).to_string(),
_ => unreachable!(),
};
if let Some(value) = &value {
match self.tabs[i].scene.set_centerline_setting(&name, value) {
Ok(message) => {
self.tabs[i].dirty = true;
self.command_line.push_output(&message);
}
Err(error) => self.command_line.push_error(&error),
}
} 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));
}
// Parse a boolean given as 0/1 or ON/OFF.
let parse_bool = |s: &str| match s.to_uppercase().as_str() {
"1" | "ON" | "TRUE" => Some(true),
+35
View File
@@ -1844,6 +1844,41 @@ impl OpenCADStudio {
&mut entity,
);
// Smart centre objects carry their own drawing-level creation style.
// Apply it after the generic ribbon style so ordinary LINE entities
// keep the existing path while centre lines honour their settings.
let center_line = acadrust::entities::CenterLineAssociation::read(
&entity.common().extended_data,
).is_some();
let center_mark = acadrust::entities::CenterMarkAssociation::read(
&entity.common().extended_data,
).is_some();
if center_line || center_mark {
let settings = self.tabs[i].scene.centerline_settings();
if !settings.layer.eq_ignore_ascii_case("Current") {
entity.common_mut().layer = settings.layer;
}
if !settings.linetype.eq_ignore_ascii_case("Current") {
entity.common_mut().linetype = settings.linetype;
}
entity.common_mut().linetype_scale = settings.linetype_scale;
let application = if center_mark {
acadrust::entities::CENTERMARK_XDATA_APPLICATION
} else {
acadrust::entities::CENTERLINE_XDATA_APPLICATION
};
if !self.tabs[i]
.scene
.document
.app_ids
.contains(application)
{
let mut app = acadrust::tables::AppId::new(application);
app.handle = self.tabs[i].scene.document.allocate_handle();
let _ = self.tabs[i].scene.document.app_ids.add(app);
}
}
let text_style_annotative = match &entity {
acadrust::EntityType::Text(text) => {
crate::scene::annotative::text_style_is_annotative(