forked from 1b-agent/opencadstudio-upstream
Merge main into codex/graphic-attributes-cleanup
Conflicts were additions on both sides, kept together: the Count palette and Sheet Set toggles next to the Graphic Attributes toggle in the ribbon, main's new locale groups and catalog entries next to graphic-attributes, and module declarations. The palette code follows main's crate renames (acadrust -> codec, cadkernel -> kernel). Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01VgkJN8DEojuPTumAXLHotu
This commit is contained in:
625 files changed
+104397
-28053
No files matched your search
+140
-37
@@ -8,21 +8,21 @@
|
||||
use crate::scene::model::hatch_model::HatchModel;
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
use crate::scene::Scene;
|
||||
use acadrust::{EntityType, Handle};
|
||||
use codec::{EntityType, Handle};
|
||||
use glam::DVec3;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum HatchEditOperation {
|
||||
Appearance {
|
||||
color: Option<acadrust::types::Color>,
|
||||
color: Option<codec::types::Color>,
|
||||
layer: Option<String>,
|
||||
transparency: Option<acadrust::types::Transparency>,
|
||||
transparency: Option<codec::types::Transparency>,
|
||||
},
|
||||
Update {
|
||||
origin: Option<(f64, f64)>,
|
||||
store_origin: bool,
|
||||
disassociate: bool,
|
||||
style: Option<acadrust::entities::HatchStyleType>,
|
||||
style: Option<codec::entities::HatchStyleType>,
|
||||
annotative: Option<bool>,
|
||||
},
|
||||
RecreateBoundary {
|
||||
@@ -30,7 +30,7 @@ pub enum HatchEditOperation {
|
||||
region: bool,
|
||||
},
|
||||
BeginAssociate,
|
||||
AssociatePaths(Vec<acadrust::entities::BoundaryPath>),
|
||||
AssociatePaths(Vec<codec::entities::BoundaryPath>),
|
||||
DrawOrderBoundary {
|
||||
above: bool,
|
||||
},
|
||||
@@ -110,8 +110,8 @@ impl WorkingPlane {
|
||||
(direction.x.hypot(direction.y) > f64::EPSILON).then(|| direction.y.atan2(direction.x))
|
||||
}
|
||||
|
||||
pub fn to_world_transform(self) -> acadrust::types::Transform {
|
||||
use acadrust::types::{Matrix4, Transform};
|
||||
pub fn to_world_transform(self) -> codec::types::Transform {
|
||||
use codec::types::{Matrix4, Transform};
|
||||
Transform::from_matrix(Matrix4 {
|
||||
m: [
|
||||
[self.x.x, self.y.x, self.z.x, self.origin.x],
|
||||
@@ -122,8 +122,8 @@ impl WorkingPlane {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn to_local_transform(self) -> acadrust::types::Transform {
|
||||
use acadrust::types::{Matrix4, Transform};
|
||||
pub fn to_local_transform(self) -> codec::types::Transform {
|
||||
use codec::types::{Matrix4, Transform};
|
||||
Transform::from_matrix(Matrix4 {
|
||||
m: [
|
||||
[self.x.x, self.x.y, self.x.z, -self.origin.dot(self.x)],
|
||||
@@ -249,18 +249,25 @@ pub enum EntityTransform {
|
||||
},
|
||||
/// General affine transform. Used when a complete UCS basis must be baked
|
||||
/// into block-local geometry instead of stored as drawing UCS state.
|
||||
Affine(acadrust::types::Transform),
|
||||
Affine(codec::types::Transform),
|
||||
}
|
||||
|
||||
// ── Tangent object ─────────────────────────────────────────────────────────
|
||||
|
||||
/// Geometric representation of a tangent-snap target.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum TangentObject {
|
||||
/// Infinite line through two world-space XZ-plane points.
|
||||
Line { p1: DVec3, p2: DVec3 },
|
||||
/// Circle in the world XY plane.
|
||||
Circle { center: DVec3, radius: f64 },
|
||||
/// Planar ellipse in world space.
|
||||
Ellipse {
|
||||
center: DVec3,
|
||||
major_axis: DVec3,
|
||||
normal: DVec3,
|
||||
minor_axis_ratio: f64,
|
||||
},
|
||||
}
|
||||
|
||||
/// One unit of input to the active command's step machine.
|
||||
@@ -417,6 +424,10 @@ impl CadCommand for UcsPickCommand {
|
||||
true
|
||||
}
|
||||
|
||||
fn entity_pick_includes_fills(&self) -> bool {
|
||||
self.face
|
||||
}
|
||||
|
||||
fn entity_pick_uses_surface_point(&self) -> bool {
|
||||
self.face
|
||||
}
|
||||
@@ -1385,6 +1396,9 @@ pub struct SweepOptions {
|
||||
pub scale: f64,
|
||||
/// Total twist along the path, in radians.
|
||||
pub twist_angle: f64,
|
||||
/// Where the path was picked: an open path is swept from its end nearest
|
||||
/// this point (seen from above), as the reference does.
|
||||
pub path_pick: Option<DVec3>,
|
||||
}
|
||||
|
||||
impl Default for SweepOptions {
|
||||
@@ -1395,6 +1409,7 @@ impl Default for SweepOptions {
|
||||
base_point: None,
|
||||
scale: 1.0,
|
||||
twist_angle: 0.0,
|
||||
path_pick: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1499,13 +1514,13 @@ pub enum CmdResult {
|
||||
InterimWire(WireModel),
|
||||
/// Update the in-progress (cyan) preview wire in the viewport.
|
||||
Preview(WireModel),
|
||||
/// Commit an acadrust entity to the document; keep the command active.
|
||||
/// Commit an opencadcodec entity to the document; keep the command active.
|
||||
CommitEntity(EntityType),
|
||||
/// Commit several acadrust entities in one undo step; keep the command active.
|
||||
/// Commit several opencadcodec entities in one undo step; keep the command active.
|
||||
CommitEntities(Vec<EntityType>),
|
||||
/// Commit several entities in one undo step and end the command.
|
||||
CommitEntitiesAndExit(Vec<EntityType>),
|
||||
/// Commit an acadrust entity to the document and end the command.
|
||||
/// Commit an opencadcodec entity to the document and end the command.
|
||||
CommitAndExit(EntityType),
|
||||
/// Commit a dimension using the drawing's association mode.
|
||||
CommitDimension {
|
||||
@@ -1534,16 +1549,16 @@ pub enum CmdResult {
|
||||
handles: Vec<Handle>,
|
||||
point: DVec3,
|
||||
},
|
||||
/// Commit a Model-tab 3D solid: the acadrust entity (for selection /
|
||||
/// Commit a Model-tab 3D solid: the opencadcodec entity (for selection /
|
||||
/// persistence) plus its B-rep (cached for boolean ops + shaded
|
||||
/// rendering). Ends the command.
|
||||
CommitSolid {
|
||||
entity: EntityType,
|
||||
solid: Box<cadkernel::brep::Body>,
|
||||
history: acadrust::objects::SolidHistoryOperation,
|
||||
solid: Box<kernel::brep::Body>,
|
||||
history: codec::objects::SolidHistoryOperation,
|
||||
erase_source: Option<Handle>,
|
||||
},
|
||||
/// Commit an acadrust entity, end the command, and open the in-place text
|
||||
/// Commit an opencadcodec entity, end the command, and open the in-place text
|
||||
/// editor on it (used by MLEADER to type the annotation after placement).
|
||||
CommitAndEditText(EntityType),
|
||||
/// Commit several entities, end the command, and open the in-place text
|
||||
@@ -1578,24 +1593,50 @@ pub enum CmdResult {
|
||||
/// Commit a hatch with the selected hatch's entity colour and transparency.
|
||||
CommitStyledHatch {
|
||||
hatch: HatchModel,
|
||||
color: acadrust::types::Color,
|
||||
transparency: acadrust::types::Transparency,
|
||||
color: codec::types::Color,
|
||||
transparency: codec::types::Transparency,
|
||||
},
|
||||
/// Commit a hatch and retain each boundary ring as an entity.
|
||||
CommitHatchWithBoundaries {
|
||||
hatch: HatchModel,
|
||||
boundaries: Vec<EntityType>,
|
||||
entity_style: Option<(acadrust::types::Color, acadrust::types::Transparency)>,
|
||||
entity_style: Option<(codec::types::Color, codec::types::Transparency)>,
|
||||
},
|
||||
/// Commit independently editable hatch entities for every selected region.
|
||||
CommitHatches {
|
||||
hatches: Vec<HatchModel>,
|
||||
entity_style: Option<(acadrust::types::Color, acadrust::types::Transparency)>,
|
||||
entity_style: Option<(codec::types::Color, codec::types::Transparency)>,
|
||||
},
|
||||
/// Copy selected entities with multiple transforms (e.g. rectangular array); end command.
|
||||
BatchCopy(Vec<Handle>, Vec<EntityTransform>),
|
||||
/// Erase `handle` and replace with new entities; command stays active.
|
||||
ReplaceEntity(Handle, Vec<EntityType>),
|
||||
/// XCLIP on block references; ends the command.
|
||||
XClip {
|
||||
inserts: Vec<Handle>,
|
||||
action: crate::modules::insert::xclip::XclipAction,
|
||||
},
|
||||
/// Open the PDF Import Settings dialog; the command keeps its prompt.
|
||||
OpenPdfImportSettings,
|
||||
/// Import a page of a file (PDFIMPORT File); ends the command.
|
||||
PdfImportFile(crate::modules::insert::pdf_import::PdfFileImport),
|
||||
/// Attach a point cloud: the host creates or reuses its definition,
|
||||
/// commits the cloud in one undo step, then ends the command. The
|
||||
/// message is the last prompt's echo.
|
||||
AttachPointCloud {
|
||||
placement: crate::modules::insert::pc_attach::PointCloudPlacement,
|
||||
message: String,
|
||||
},
|
||||
/// Attach PDF pages: each page's underlay with its file (as stored) and
|
||||
/// page; the host creates or reuses the definitions and commits them all
|
||||
/// in one undo step, then ends the command.
|
||||
AttachPdfPages {
|
||||
kind: codec::entities::UnderlayType,
|
||||
path: String,
|
||||
pages: Vec<(String, EntityType)>,
|
||||
},
|
||||
/// Import the vector content of a PDF underlay (PDFIMPORT); ends the command.
|
||||
PdfImport(crate::modules::insert::pdf_import::PdfImportRequest),
|
||||
/// Update one entity in place, preserve its handle, and end the command.
|
||||
UpdateEntityAndFinish {
|
||||
handle: Handle,
|
||||
@@ -1633,7 +1674,7 @@ pub enum CmdResult {
|
||||
AddHorizontalConstraint {
|
||||
kind: crate::scene::parametric_constraints::ConstraintKind,
|
||||
selection: HorizontalConstraintSelection,
|
||||
direction: acadrust::types::Vector3,
|
||||
direction: codec::types::Vector3,
|
||||
label: &'static str,
|
||||
},
|
||||
/// Resolves the first 2Points pick of a Horizontal or Vertical constraint
|
||||
@@ -1895,6 +1936,12 @@ pub enum CmdResult {
|
||||
ReportError(String),
|
||||
/// Reports an error and ends the command (`Lines are parallel.`).
|
||||
CancelWithMessage(String),
|
||||
/// Explode this block reference and commit its pieces; end the command
|
||||
/// unless `keep_going` (repeated placement).
|
||||
CommitExplodedInsert {
|
||||
insert: EntityType,
|
||||
keep_going: bool,
|
||||
},
|
||||
/// Print a measurement result, clear the current selection, and keep the command active.
|
||||
ReportMeasurementAndDeselect(String),
|
||||
/// Clear the current selection and keep the command active at its updated step.
|
||||
@@ -1952,7 +1999,7 @@ pub enum CmdResult {
|
||||
/// Create a paper-space viewport. `preserve_view` keeps an explicitly
|
||||
/// selected/defined view instead of applying the normal model-extents fit.
|
||||
MviewCreate {
|
||||
viewport: acadrust::entities::Viewport,
|
||||
viewport: codec::entities::Viewport,
|
||||
preserve_view: bool,
|
||||
},
|
||||
/// Create a viewport clipped by either a new polygon boundary or an
|
||||
@@ -1960,6 +2007,9 @@ pub enum CmdResult {
|
||||
MviewCreateClipped {
|
||||
boundary: Option<EntityType>,
|
||||
boundary_handle: Handle,
|
||||
/// VPCLIP: the viewport to clip instead of creating one (NULL for
|
||||
/// MVIEW). With neither boundary nor handle its clip is deleted.
|
||||
target: Handle,
|
||||
},
|
||||
/// Create a wipeout from an existing closed polyline in the active space.
|
||||
/// `erase_source` controls whether the source boundary is consumed.
|
||||
@@ -2001,7 +2051,7 @@ pub enum CmdResult {
|
||||
/// command (boundary, rotation, attachment, spacing and columns).
|
||||
/// Existing-entity edits leave this as `None` and load the document
|
||||
/// entity instead.
|
||||
template: Option<Box<acadrust::MText>>,
|
||||
template: Option<Box<codec::MText>>,
|
||||
},
|
||||
/// Collect rich text without creating an MText entity.
|
||||
SuspendForMTextInput {
|
||||
@@ -2024,7 +2074,7 @@ pub enum CmdResult {
|
||||
/// the command resumes so another line can be placed directly below it.
|
||||
SuspendForTextInput {
|
||||
pos: DVec3,
|
||||
entity: acadrust::entities::Text,
|
||||
entity: codec::entities::Text,
|
||||
},
|
||||
/// Apply new pattern/scale/angle to an existing hatch entity.
|
||||
HatcheditApply {
|
||||
@@ -2094,6 +2144,9 @@ pub enum CmdResult {
|
||||
mode: ExtrudeMode,
|
||||
options: SweepOptions,
|
||||
color: [f32; 4],
|
||||
/// Scale and twist expressions entered with the Expression option;
|
||||
/// a swept surface stays linked to them.
|
||||
expressions: [Option<String>; 2],
|
||||
},
|
||||
/// Loft through ordered cross-sections, with optional guides or a path.
|
||||
LoftEntities {
|
||||
@@ -2107,8 +2160,8 @@ pub enum CmdResult {
|
||||
/// Round or bevel one or more resolved B-rep edges on a solid.
|
||||
SolidEdgeBlend {
|
||||
handle: Handle,
|
||||
edges: Vec<cadkernel::brep::EdgeKey>,
|
||||
base_face: Option<cadkernel::brep::FaceKey>,
|
||||
edges: Vec<kernel::brep::EdgeKey>,
|
||||
base_face: Option<kernel::brep::FaceKey>,
|
||||
value: f64,
|
||||
other_value: f64,
|
||||
fillet: bool,
|
||||
@@ -2129,13 +2182,13 @@ pub enum CmdResult {
|
||||
/// containing that WCS point.
|
||||
SliceEntities {
|
||||
targets: Vec<Handle>,
|
||||
plane: cadkernel::space::Plane,
|
||||
plane: kernel::space::Plane,
|
||||
keep_point: Option<DVec3>,
|
||||
},
|
||||
/// Split selected solids or surfaces with one selected analytic sheet.
|
||||
SliceSurfaceEntities {
|
||||
targets: Vec<Handle>,
|
||||
cutter: Box<cadkernel::brep::Body>,
|
||||
cutter: Box<kernel::brep::Body>,
|
||||
keep_point: Option<DVec3>,
|
||||
},
|
||||
/// INSERT landed on a block that has AttributeDefinitions.
|
||||
@@ -2426,7 +2479,7 @@ pub trait CadCommand: Send {
|
||||
None
|
||||
}
|
||||
/// Symbol localization is committed together with the extracted entities.
|
||||
fn nested_copy_symbol_names(&self) -> Option<&acadrust::nested_copy::NestedCopySymbolNames> {
|
||||
fn nested_copy_symbol_names(&self) -> Option<&codec::nested_copy::NestedCopySymbolNames> {
|
||||
None
|
||||
}
|
||||
/// Keep the layer already carried by entities committed by this command
|
||||
@@ -2632,6 +2685,12 @@ pub trait CadCommand: Send {
|
||||
/// Resume the command with collected rich text.
|
||||
fn on_editor_text(&mut self, _value: String) {}
|
||||
|
||||
/// A field (code and referenced objects) to attach to the entity this
|
||||
/// command commits.
|
||||
fn text_field(&self) -> Option<(String, Vec<Handle>)> {
|
||||
None
|
||||
}
|
||||
|
||||
fn on_editor_display_height(&mut self, _height: f64) {}
|
||||
|
||||
/// Called when the user clicks and `needs_entity_pick()` is true.
|
||||
@@ -2699,6 +2758,12 @@ pub trait CadCommand: Send {
|
||||
/// Commands that stay active across replaces should update their internal snapshots here.
|
||||
fn on_entity_replaced(&mut self, _old: Handle, _new_handles: &[Handle]) {}
|
||||
|
||||
/// Called after `CmdResult::CommitEntity` / `CommitEntities` added
|
||||
/// entities while the command stays active, with the entities as stored
|
||||
/// (fresh handles). Commands that pick from a snapshot add them here so
|
||||
/// their own results can be hovered and picked next. (#673)
|
||||
fn on_entities_committed(&mut self, _entities: &[codec::EntityType]) {}
|
||||
|
||||
/// Called after a PEDIT operation changed its target.
|
||||
fn on_pedit_applied(&mut self) {}
|
||||
|
||||
@@ -2747,6 +2812,16 @@ pub trait CadCommand: Send {
|
||||
self.on_mouse_move(pt).into_iter().collect()
|
||||
}
|
||||
|
||||
/// Called on every mouse-move with optional live tangent snap target under the cursor.
|
||||
/// Default: forwards to `on_preview_wires(pt)`.
|
||||
fn on_preview_wires_with_tangent(
|
||||
&mut self,
|
||||
pt: DVec3,
|
||||
_tangent: Option<TangentObject>,
|
||||
) -> Vec<WireModel> {
|
||||
self.on_preview_wires(pt)
|
||||
}
|
||||
|
||||
/// Source entities replaced by the current live preview. The host removes
|
||||
/// these from the resident render until the command commits or cancels.
|
||||
/// Commands such as COPY keep their sources visible and use the default.
|
||||
@@ -2832,6 +2907,22 @@ pub trait CadCommand: Send {
|
||||
false
|
||||
}
|
||||
|
||||
/// The command takes block references only (XCLIP): the host drops the
|
||||
/// rest and says how many were ineligible.
|
||||
fn selection_keeps_block_references(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// The command moves, turns or resizes what it gathers: the host drops
|
||||
/// locked point clouds from each completed selection and says so.
|
||||
fn selection_drops_locked_point_clouds(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Before each input the host says which block references carry a clip
|
||||
/// boundary.
|
||||
fn inject_clipped(&mut self, _clipped: &dyn Fn(Handle) -> bool) {}
|
||||
|
||||
/// Called after a selection action completes while `is_selection_gathering` is true.
|
||||
/// `handles` is the full set of currently selected entities.
|
||||
/// Return `Relaunch` to fire the pending command, or `NeedPoint` to keep gathering.
|
||||
@@ -2864,6 +2955,12 @@ pub trait CadCommand: Send {
|
||||
false
|
||||
}
|
||||
|
||||
/// The step draws a window that selects objects rather than placing
|
||||
/// geometry: no coordinate boxes at the cursor. Default `false`.
|
||||
fn selects_by_window(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// The already-picked first corner of the selection window (world space)
|
||||
/// while `window_corner_pick()` is true and the opposite corner is being
|
||||
/// dragged. The host projects it and draws a filled selection marquee to the
|
||||
@@ -2886,22 +2983,28 @@ pub trait CadCommand: Send {
|
||||
|
||||
/// The block reference an ATTEDIT pick has resolved to, awaiting the
|
||||
/// attribute editor dialog; else None.
|
||||
fn attedit_pending_handle(&self) -> Option<acadrust::Handle> {
|
||||
fn attedit_pending_handle(&self) -> Option<codec::Handle> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Inject block attribute definitions after the INSERT point is picked.
|
||||
fn attreq_set_attdefs(
|
||||
&mut self,
|
||||
_attdefs: Vec<acadrust::entities::AttributeDefinition>,
|
||||
) -> Option<acadrust::EntityType> {
|
||||
_attdefs: Vec<codec::entities::AttributeDefinition>,
|
||||
) -> Option<codec::EntityType> {
|
||||
None
|
||||
}
|
||||
|
||||
/// After the host commits an ATTREQ insert: keep the command running
|
||||
/// (repeated placement) instead of ending it.
|
||||
fn attreq_continue(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Returns the INSERT entity built so far (pending attr fill) if this is an
|
||||
/// ATTREQ-aware INSERT command waiting for attdef injection.
|
||||
/// Called by the host after `AttreqNeeded` to commit the completed Insert.
|
||||
fn attreq_take_insert(&mut self) -> Option<acadrust::EntityType> {
|
||||
fn attreq_take_insert(&mut self) -> Option<codec::EntityType> {
|
||||
None
|
||||
}
|
||||
|
||||
@@ -2944,13 +3047,13 @@ pub trait CadCommand: Send {
|
||||
/// Called by update.rs to inject the cloned entity into commands
|
||||
/// that need to read/modify it (e.g. DIMTEDIT, MLEADERADD, MLEADERREMOVE).
|
||||
/// Default: no-op.
|
||||
fn inject_picked_entity(&mut self, _entity: acadrust::EntityType) {}
|
||||
fn inject_picked_entity(&mut self, _entity: codec::EntityType) {}
|
||||
|
||||
/// The host undid one document step on the command's behalf
|
||||
/// (`CmdResult::UndoDocument`) and the command stays active. Commands
|
||||
/// that cache document entities (FILLET, CHAMFER) refresh them here so
|
||||
/// the next pick sees the restored geometry. Default: no-op.
|
||||
fn on_document_undone(&mut self, _document: &acadrust::CadDocument) {}
|
||||
fn on_document_undone(&mut self, _document: &codec::CadDocument) {}
|
||||
|
||||
/// Supply the tessellated surface area associated with the picked entity.
|
||||
/// Commands that measure mesh-backed objects can opt in without owning the
|
||||
|
||||
Reference in new issue
Block a user