mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-18 14:32:36 +00:00
m_hole_on_face and m_thread_on_face are cleared only by their tool's flyout and by their plane combobox, so after any on-face hole or thread the flag stays true for the rest of the session. load_feature_into_dialog restored the stored plane into the dropdown but never touched the latch, so re-editing from the feature tree ignored the plane it had just restored: hole_plane() returned the still-latched face plane, which may belong to a different face, a different body, or a body since rebuilt. Silent until snaporca-200 added the "On face" row, which then read as a confidently wrong answer rather than as nothing. The latch is now rebuilt from the stored feature, which is the only source that describes THIS hole. Not from the dropdown row: index_from_plane snaps an arbitrary face plane to the nearest XY/XZ/YZ, so driving the re-edit from the row would MOVE a hole drilled on a slanted or offset face — that was the reason the other candidate fix was rejected. is_base_plane() decides which of the two a stored plane is. It compares the origin as well as the axes (a plane parallel to XY but 12 mm up snaps to row 0 and would come back at z=0), and adds modeling_origin before comparing, because hole_plane() and thread_plane() add it to the dropdown plane before the feature stores it — a document with a shifted origin would otherwise mistake every dropdown hole for a face pick. Vector norms, not isApprox, which is relative to magnitude and useless against the zero origin. The face's (u,v) extent is not serialized, so m_hole_has_bounds is cleared: the gizmo's footprint clamp goes unbounded, which is honest, where another face's bounds are not. The label says which body the face belongs to instead of a face number the feature does not carry; "(none — uses Hole plane)" is the one thing that is definitely false there. snaporca-uif9. Reviewed and compiled (RC=0), not exercised.