Files
solvecraft/apps
Kai Evans a74e78fba8 Chamfer and fillet: an edge on a moved part is found where you picked it (#13239)
A chamfer or fillet without `body` on a moved part failed with
"[20, 0, 0] is where 2 edges meet". This happened when another part
had an edge at that point in its own frame. Take 2 parts that meet
in the world, but not in their own frames. A pick on the shared edge
cut the first part. edge_points looked for edges on every body in
that body's own frame. It ignored the world point of the pick.

- frames.rs remembers the world point of every pick, face or not.
  picked_world(local, nth) returns it. nth keeps 2 picks at one local
  point apart.
- edge_points maps the world point into each placed body's frame,
  hidden placements too. The world rows are built on first use. A
  body's box, grown by the reach, culls it. The polylines short-list
  edges. The exact curves decide (edge_foot: 33 samples, then a
  golden-section search). Bodies within 2 d + 1e-3 mm of the nearest
  refuse the pick. The reply names both: "[20, 0, 0] lies on edges of
  2 bodies, Base block and Cap block: name the one to chamfer with
  `body`". A hidden body adds "(X is hidden)".
- A seam at the pick, with no edge there, adds no second body.
- 2 placements of one body at one edge, or one local point, are 1 edge.
- With no placement to look through, the pick uses the bodies' own
  frames. That happens when every frame is singular. The pick is not
  passed unchecked.
- A pick's own `body` must exist and agree with `body`. Else the
  command refuses: "an edge names `Cap block`, but `body` is `Base
  block`: give one". Main finds the pick on Cap and cuts Base.
- The corner check runs on the body found. Corner and no-edge
  refusals print the world point.
- With 2 or more bodies, the feature keeps the body found as `body`.
  Picks on 2 or more bodies get 1 more check. If another
  body's frame has an edge at a pick's point, the command refuses. The
  reply asks for "each body in a command of its own". The ghost check
  skips edges whose polyline is too far before it runs edge_foot.
- solid.press_pull forwards `body` to the fillet. Its frames entry
  maps `body`, and its params name it.
- The fillet schema and the fillet and chamfer params describe the
  lookup.

Changes a default: no. Calls that cut the wrong part now refuse,
naming both parts. So do picks on the cut of a split body. A pick
whose own `body` disagrees with `body` refuses too. Dialogs already
send `body`.

Synthetic scripts ran against 6a1fe7468 (solidcraft-cli run,
--profile ci). 4 picks now cut the picked part, where main refused:
- Base's edge, with Cap moved 50 mm up.
- The same, with the root active and Cap moved 500 mm along x.
- Cap's edge at its world point.
- Base's edge with tangent_chain false.
Parts meeting in one frame or in the world are refused, naming
both. Press Pull there is refused too; main rounds Base block. A box
edge on a cylinder's seam is cut; main tries the seam and fails.

Tests: 19 in frames_tests.rs (16) and tests.rs (3). 16 fail on
6a1fe7468. 3 pass there: hostile picks, a singular placement, and 2
placements of one part. action_matrix
edge_round_actions_keep_the_picked_body expects the new refusal.

cargo xtask ci: 13948 passed, 32 failed, 67 ignored, 89 binaries.
- 22 failures are in tests/KNOWN_FAILING_TESTS.
- 7 fail alone on 6a1fe7468 too:
  3 pleat tests (FilletRearOuter, SMLib status 1001),
  smlib a_cylinder_side_section_is_its_circle,
  gpu gpu_thin_lens_focus_and_defocus_match_geometric_oracle,
  ui-egui the_extrude_arrow_passes_faces_beside_the_profile_and_in_a_free_drag,
  kernel boolean_props translation_invariant (a random 2-sphere case).
- 3 ui-egui agent_chat tests pass alone on both trees.
2026-11-08 05:19:04 +00:00
..