forked from 1b-agent/opencadstudio-upstream
Merge pull request #1356 from ramox81/codex/fixed-constraint-parity
Match Fix geometric constraint behavior # Conflicts: # src/scene/parametric_constraints.rs # src/scene/parametric_solve.rs
This commit is contained in:
commit
7ef4e9f336
9 files changed
+572
-203
No files matched your search
@@ -593,7 +593,29 @@ impl ParametricConstraintSet {
|
||||
///
|
||||
/// Solver-side registration reads raw entity fields directly. This helper is
|
||||
/// for UI-side consumers that need the current world-space position.
|
||||
/// The single addressable point (marker `0`) of a point-like entity: the
|
||||
/// node, insertion, or table origin the solver registers as its
|
||||
/// `EntityGeom::Point` / text baseline start. `None` for curve entities,
|
||||
/// whose marker `0` is a `source_points()` endpoint.
|
||||
pub(crate) fn insertion_point(entity: &acadrust::EntityType) -> Option<Vector3> {
|
||||
match entity {
|
||||
acadrust::EntityType::Point(point) => Some(point.location),
|
||||
acadrust::EntityType::Insert(insert) => Some(insert.insert_point),
|
||||
acadrust::EntityType::Text(text) => Some(text.insertion_point),
|
||||
acadrust::EntityType::MText(text) => Some(text.insertion_point),
|
||||
acadrust::EntityType::AttributeDefinition(attribute) => Some(attribute.insertion_point),
|
||||
acadrust::EntityType::AttributeEntity(attribute) => Some(attribute.insertion_point),
|
||||
acadrust::EntityType::Table(table) => Some(table.insertion_point),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn resolve_point(entity: &acadrust::EntityType, marker: i32) -> Option<Vector3> {
|
||||
if marker == 0 {
|
||||
if let Some(point) = insertion_point(entity) {
|
||||
return Some(point);
|
||||
}
|
||||
}
|
||||
if marker == -3 {
|
||||
return match entity {
|
||||
acadrust::EntityType::Circle(circle) => Some(circle.center_wcs()),
|
||||
@@ -651,6 +673,12 @@ pub(crate) fn parametric_point_candidates(
|
||||
.enumerate()
|
||||
.map(|(marker, point)| (marker as i32, point))
|
||||
.collect();
|
||||
// A node / insertion point is a constraint point too (the reference
|
||||
// fixes a POINT via NODe and TEXT via INSert), and these entities have
|
||||
// no `source_points()` to collide with marker `0`.
|
||||
if let Some(point) = insertion_point(entity) {
|
||||
points.push((0, point));
|
||||
}
|
||||
match entity {
|
||||
acadrust::EntityType::Circle(circle) => points.push((-3, circle.center_wcs())),
|
||||
acadrust::EntityType::Arc(arc) => points.push((-3, arc.center_wcs())),
|
||||
@@ -869,6 +897,23 @@ impl ConstraintKind {
|
||||
}
|
||||
}
|
||||
|
||||
/// Fixed draws a padlock (`src/ui/overlay.rs`), the way the reference bar
|
||||
/// does: the plain symbol for a held curve or segment, this variant when one
|
||||
/// addressable point is held (white lock with the point marker).
|
||||
pub(crate) const FIXED_POINT_GLYPH: &str = "F·";
|
||||
|
||||
pub(crate) fn fixed_glyph_label(constraint: &ParametricConstraint) -> &'static str {
|
||||
let point = constraint
|
||||
.refs
|
||||
.first()
|
||||
.is_some_and(|reference| reference.marker.is_some() && reference.segment_index().is_none());
|
||||
if point {
|
||||
FIXED_POINT_GLYPH
|
||||
} else {
|
||||
ConstraintKind::Fixed.glyph_symbol()
|
||||
}
|
||||
}
|
||||
|
||||
/// The full glyph text for one constraint: its symbol, plus the driving
|
||||
/// value for a dimensional kind (Distance/Angle/Radius).
|
||||
pub(crate) fn glyph_label(constraint: &ParametricConstraint) -> String {
|
||||
@@ -1672,7 +1717,9 @@ impl super::Scene {
|
||||
})
|
||||
.flat_map(|c| {
|
||||
let is_conflicting = set.conflicts.iter().any(|(id, _)| *id == c.id);
|
||||
let base_label = if show_values {
|
||||
let base_label = if c.kind == ConstraintKind::Fixed {
|
||||
fixed_glyph_label(c).to_string()
|
||||
} else if show_values {
|
||||
glyph_label(c)
|
||||
} else {
|
||||
c.kind.glyph_symbol().to_string()
|
||||
|
||||
Reference in new issue
Block a user