Merge current main with division marker support

This commit is contained in:
ramox81 committed 2026-09-11 15:23:05 +03:00
commit f076db6d53
160 files changed
+16859 -16176

No files matched your search

+123 -2
View File
@@ -13,13 +13,22 @@ use glam::DVec3;
#[derive(Clone, Debug)]
pub enum HatchEditOperation {
Appearance {
color: Option<acadrust::types::Color>,
layer: Option<String>,
transparency: Option<acadrust::types::Transparency>,
},
Update {
origin: Option<(f64, f64)>,
store_origin: bool,
disassociate: bool,
style: Option<acadrust::entities::HatchStyleType>,
annotative: Option<bool>,
},
RecreateBoundary,
RecreateBoundary { associate: bool, region: bool },
BeginAssociate,
AssociatePaths(Vec<acadrust::entities::BoundaryPath>),
DrawOrderBoundary { above: bool },
Separate,
AddBoundaries(Vec<Handle>),
RemoveBoundaries(Vec<Handle>),
@@ -1408,6 +1417,60 @@ pub enum CmdResult {
ReplaceMany(Vec<(Handle, Vec<EntityType>)>, Vec<EntityType>),
/// Replace several entities as one undo step while keeping the command active.
ReplaceManyContinue(Vec<(Handle, Vec<EntityType>)>),
/// Add a persistent parametric constraint to the current scope's
/// `SketchConstraintSet` and trigger its
/// first solve; end the command. Unlike `ReplaceMany`/`CommitEntity`,
/// nothing here is geometry to add or replace directly — the host adds
/// the constraint record, then re-solves through `Scene::bump_entities`'s
/// existing chain (`refresh_sketch_constraints`) the same way any later
/// edit to these entities will.
AddSketchConstraint {
kind: crate::scene::sketch_constraints::ConstraintKind,
refs: Vec<crate::scene::sketch_constraints::SketchRef>,
/// The typed target for a dimensional kind (Distance/Angle/Radius) —
/// a literal number, or a named-parameter reference recognized by
/// `DistanceConstraintCommand`/`AngleConstraintCommand::
/// on_text_input` when the typed token matches a known parameter
/// name instead of parsing as a number); `None` for a purely
/// geometric kind.
driving_param: Option<crate::scene::named_parameters::DrivingValue>,
/// Undo-history label, e.g. `"Horizontal constraint"`.
label: &'static str,
},
/// Adds a Coincident constraint between the sub-entity points nearest
/// the two picked positions. The host resolves the raw points because
/// `CadCommand` has no document access.
AddCoincidentConstraint {
point_a: DVec3,
point_b: DVec3,
label: &'static str,
},
/// Add a persistent `CenterPoint`/`Midpoint`/`PointOnCurve` constraint
/// (`crate::modules::draw::constrain::point_on_entity`) between one
/// picked point and `target`, a whole entity selected before the tool
/// ran. Like `AddCoincidentConstraint`, the host resolves `point` via
/// `sketch_constraints::nearest_sketch_point` (a `CadCommand` has no
/// document access) and, for `CenterPoint` specifically, addresses
/// `target` via its center marker rather than as a whole entity — see
/// `ConstraintKind::CenterPoint`'s own doc comment for why it's the
/// same solve as `Coincident`/`Concentric` under a different DWG-native
/// class name.
AddPointOnEntityConstraint {
point: DVec3,
target: Handle,
kind: crate::scene::sketch_constraints::ConstraintKind,
label: &'static str,
},
/// Add a persistent `EqualDistance` constraint
/// (`crate::modules::draw::constrain::equal_distance`): the distance
/// between `points[0]`/`points[1]` equals the distance between
/// `points[2]`/`points[3]`. The host resolves each point via
/// `sketch_constraints::nearest_sketch_point`, same reasoning as
/// `AddCoincidentConstraint`.
AddEqualDistanceConstraint {
points: [DVec3; 4],
label: &'static str,
},
/// Attach one smart centre mark to a newly selected circular source.
ReassociateCenterMark {
target: Handle,
@@ -1475,6 +1538,8 @@ pub enum CmdResult {
BreakEntity { handle: Handle, p1: DVec3, p2: DVec3 },
/// Attempt to join the given entities into fewer merged entities.
JoinEntities(Vec<Handle>),
/// Join candidates into an explicitly selected source.
JoinToSource { source: Handle, handles: Vec<Handle> },
/// Apply a polyline-edit operation to one entity; keep command active.
PeditOp {
handle: Handle,
@@ -1947,7 +2012,21 @@ pub struct CurveMarker {
}
/// Current screen projection and configured aperture for point-feature picking.
#[derive(Clone, Copy)]
pub struct PointPickContext {
pub view: glam::Mat4,
pub eye: DVec3,
pub bounds: iced::Rectangle,
pub aperture_px: f32,
}
pub trait CadCommand: Send {
/// Preserve source appearance for commands that extract existing entities.
fn preserve_commit_style(&self) -> bool { false }
fn nested_copy_bind_setting(&self) -> Option<bool> { None }
/// Symbol localization is committed together with the extracted entities.
fn nested_copy_symbol_names(&self) -> Option<&acadrust::nested_copy::NestedCopySymbolNames> { None }
/// Keep the layer already carried by entities committed by this command
/// instead of replacing it with the current drawing layer.
fn preserve_commit_layer(&self) -> bool {
@@ -2014,6 +2093,12 @@ pub trait CadCommand: Send {
/// Called when the user left-clicks in the viewport (point pick).
fn on_point(&mut self, pt: DVec3) -> CmdResult;
/// Opt in only while a point input selects an existing point feature.
fn wants_point_pick_context(&self) -> bool { false }
/// Refreshed for each point input so zoom and viewport changes are reflected.
fn set_point_pick_context(&mut self, _context: Option<PointPickContext>) {}
/// Called when the user presses Enter (finalize / next option).
fn on_enter(&mut self) -> CmdResult;
@@ -2294,6 +2379,9 @@ pub trait CadCommand: Send {
CmdResult::Cancel
}
/// Exclude locked-layer entities from injected selection geometry.
fn selection_entities_exclude_locked(&self) -> bool { false }
fn inject_selection_entities(&mut self, _entities: Vec<SelectionEntity>) {}
fn area_preview_regions(&self) -> Option<Vec<AreaPreviewRegion>> {
@@ -2478,6 +2566,40 @@ pub fn all_registered_command_names() -> Vec<&'static str> {
.collect()
}
#[cfg(test)]
mod constraint_registry_tests {
use super::*;
/// Ensures every constraint command remains discoverable by autocomplete
/// and command listings.
#[test]
fn every_constraint_command_is_in_the_autocomplete_registry() {
let names = all_registered_command_names();
for id in [
"CCONSTRAINT",
"EDCONSTRAINT",
"CPCONSTRAINT",
"MPCONSTRAINT",
"OCCONSTRAINT",
"HCONSTRAINT",
"VCONSTRAINT",
"PCONSTRAINT",
"QCONSTRAINT",
"ECONSTRAINT",
"TCONSTRAINT",
"NCONSTRAINT",
"NRCONSTRAINT",
"LCONSTRAINT",
"FXCONSTRAINT",
"SYCONSTRAINT",
"DCONSTRAINT",
"ACONSTRAINT",
] {
assert!(names.contains(&id), "{id} is missing from the command registry");
}
}
}
#[cfg(test)]
mod tests {
use super::*;
@@ -2516,4 +2638,3 @@ mod tests {
assert!(names.contains(&"M2P"));
}
}