FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

slvs: satisfied PT_ON_LINE moves geometry (aux param t never initialized) · Issue #1775 · solvespace/solvespace · GitHub

slvs: satisfied PT_ON_LINE moves geometry (aux param t never initialized) #1775

Description

System information

  • slvs Python package 3.2 (PyPI wheel), Linux x86_64, Python 3.13
  • Code inspected: master, src/slvs/lib.cpp and src/constrainteq.cpp

Expected behavior

Solving a sketch whose constraints are already satisfied should leave the geometry where it is. A point that already lies on a line should stay there, and so should the line.

Actual behavior

With the sketch solving API (clear_sketch / add_* / solve_sketch), a satisfied PT_ON_LINE constraint moves the geometry. PT_ON_LINE gets an auxiliary parameter t (ptOnLine = a + t*(b - a)), and the library creates it with t = 0 and never adjusts it. So the solver treats the point as if it had to sit on the line's start point, and the Newton step spreads the correction over the point and both line endpoints.

Applications that rebuild the system before every solve (e.g. the CAD Sketcher Blender add-on) see the geometry creep on every solve. Tangent constructions built from a helper point on a line drift the same way.

Steps to reproduce

import slvs

slvs.clear_sketch()
g0, g = 1, 3
o = slvs.add_point_3d(g0, 0, 0, 0)
n = slvs.add_normal_3d(g0, 1, 0, 0, 0)
wp = slvs.add_workplane(g0, o, n)

a = slvs.add_point_2d(g, 0.0, 0.0, wp)
b = slvs.add_point_2d(g, 5.0, 1.0, wp)
p = slvs.add_point_2d(g, 2.5, 0.5, wp)  # exactly on line a-b (t = 0.5)
line = slvs.add_line_2d(g, a, b, wp)
slvs.coincident(g, p, line, wp)  # -> PT_ON_LINE

print(slvs.solve_sketch(g, True))
print([round(slvs.get_param_value(h), 5) for e in (a, b, p) for h in e["param"][:2]])

Output:

({'result': 0, 'dof': 5, 'nbad': 0}, [])
[0.09012, 0.01802, 5.00072, 1.00014, 2.40915, 0.48183]

Expected [0.0, 0.0, 5.0, 1.0, 2.5, 0.5]. If p is placed at a (t = 0) nothing moves, which points at the uninitialized t. For comparison, PT_LINE_DISTANCE with value 0 (no auxiliary parameter) leaves the same geometry untouched, and so does PT_ON_CIRCLE.

Cause

Slvs_SolveSketch calls ModifyToSatisfy() on a freshly generated constraint parameter only if Slvs_CanInitiallySatisfy() returns true, and PT_ON_LINE is in the false group:

case ConstraintBase::Type::POINTS_COINCIDENT:
case ConstraintBase::Type::PT_ON_LINE:
case ConstraintBase::Type::SYMMETRIC:
...
    // Can't initially satisfy these constraints
    return false;

That list was added in cbcc5f5 (#1562) to avoid the single-equation assertion in the generic branch of ModifyToSatisfy(). PT_ON_LINE never reaches that branch, though: ModifyToSatisfy() has a dedicated case that sets t by projecting the point onto the line (constrainteq.cpp, else if(type == Type::PT_ON_LINE)). Before #1562 the library called ModifyToSatisfy() unconditionally, so this looks like a regression.

Suggested fix

Move PT_ON_LINE to the return true group in Slvs_CanInitiallySatisfy(), so its t is set from the current geometry.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL