mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-18 22:42:37 +00:00
Design: draw the mate connector, so its verse and polarity are visible
A mate connector was visible only to a program. resolve_datum_coordsys had exactly ONE consumer in the whole tree -- McpControl.cpp, the agent socket -- so the frame every mate is built on could not be seen at all, and the two questions a connector has to answer on sight had no answer in the viewport: which way does Z point (the VERSE), and which of the pair is anchored versus about to move (the POLARITY). The glyph is Onshape's proven core plus the part nobody ships. Disc for the XY plane, one gold quadrant for the roll -- the only in-glyph answer to "where is X", which matters because Fastened and Slider lock the clocking -- and a Z arrow drawn on +Z ONLY, never double-headed. Polarity is carried by the head: a filled cone travels, an open collar receives. Onshape, Fusion, Inventor and FreeCAD all draw both ends of a mate identically, which is why "which part moves?" is a standing complaint; nothing here invents new semantics, it just stops hiding them. Polarity is read from the committed Mate features, not only from the open card. A connector some mate drives must read as driven whenever it is on screen, or the glyph tells the truth only while a dialog happens to be open. The card, when open, still wins -- that is the live intent. Judged on the rig rather than in a mock, which changed three decisions: - Three RGB axis arms lose to one Z arrow. Rendered side by side (SNAPORCA_GLYPH=A selects the Onshape-style trio), the three heads are as large as the 22 px disc, they bury the quadrant, and at an oblique angle they pile into a smudge -- and the trio is indistinguishable from the move gizmo and the bed triad, which are already RGB arrow trios in this viewport. - Depth off floats, depth on tears. With GL_DEPTH_TEST off, connectors on faces pointing AWAY from the camera drew their discs over the solid, so the part looked covered in frames that were on its back. Turning depth on fixed that and immediately z-fought: the disc is exactly coplanar with its face and came out a broken dotted arc. Depth ON plus a 0.7*upp lift along Z buys both, and scaling the lift by upp keeps it sub-pixel instead of opening a visible gap on zoom-in. - Foreshortening degenerates an arrow into a dot when the axis points at the camera. It now draws a ring instead of silently vanishing, which is what a naive projection does. Everything is sized in screen pixels via upp = 1/zoom, like every other gizmo here: a connector is a symbol, not a part, so it must not shrink with the model. Research and the empirical findings are written up in DESIGN_MATE_CONNECTORS.md section 8b; rig images in artifacts/shots/g-0*.png, vendor reference glyphs in artifacts/glyphs/. Not fixed here, and recorded rather than papered over: the quadrant collapses to a blob at a grazing angle, which is exactly when the roll is hardest to read (F4); roll-undefined in red makes the least important connector the loudest thing on screen (F5); and a true grazing view, a curved face, and overlap with the move gizmo are still untested. Also surfaced while testing and unrelated to drawing: add_mate accepted a mate between two connectors on the SAME body and duly transformed the body relative to itself -- a concrete instance of the missing validation already filed as G6. Fork parity unchanged: DesignCanvas.cpp 16, DesignPanel.cpp 30, the other four files 0.
This commit is contained in:
@@ -8815,6 +8815,51 @@ void DesignPanel::refresh_datum_planes()
|
||||
if (f.type == CadFeatureType::Plane && f.enabled)
|
||||
dsizes.emplace_back(f.plane_u_size, f.plane_v_size);
|
||||
m_viewport->set_datum_planes(std::move(dplanes), std::move(dsizes));
|
||||
refresh_mate_connectors();
|
||||
}
|
||||
|
||||
// Feed the connector frames to the viewport. resolve_datum_coordsys() emits them in document order
|
||||
// over enabled CoordSys features, so the feature index can be recovered by walking the same filter —
|
||||
// which is what tells us whether a given frame is the one the open Mate card will DRIVE.
|
||||
void DesignPanel::refresh_mate_connectors()
|
||||
{
|
||||
if (!m_viewport) return;
|
||||
// Polarity is a property of the MATE, not of an open dialog: a connector that some committed
|
||||
// mate drives must read as driven whenever it is on screen, or the glyph only tells the truth
|
||||
// while a card happens to be open. The card, when open, wins — it is the live intent.
|
||||
std::map<int, int> role_by_feature; // feature index -> 1 fixed, 2 driven
|
||||
for (const CadFeature& mf : m_doc.features) {
|
||||
if (mf.type != CadFeatureType::Mate || !mf.enabled) continue;
|
||||
if (mf.mate_cs_a >= 0) role_by_feature[mf.mate_cs_a] = 1;
|
||||
if (mf.mate_cs_b >= 0) role_by_feature[mf.mate_cs_b] = 2;
|
||||
}
|
||||
const int cs_a = (m_active == Tool::Mate && m_mate_cs_a) ? m_mate_cs_a->GetSelection() : -1;
|
||||
const int cs_b = (m_active == Tool::Mate && m_mate_cs_b) ? m_mate_cs_b->GetSelection() : -1;
|
||||
|
||||
std::vector<DesignSketchTool::MateConnectorGlyph> out;
|
||||
const auto frames = m_doc.resolve_datum_coordsys();
|
||||
size_t k = 0;
|
||||
for (size_t i = 0; i < m_doc.features.size() && k < frames.size(); ++i) {
|
||||
const CadFeature& f = m_doc.features[i];
|
||||
if (f.type != CadFeatureType::CoordSys || !f.enabled) continue;
|
||||
const auto& fr = frames[k];
|
||||
const int ordinal = int(k);
|
||||
++k;
|
||||
if (!fr.error.empty()) continue; // unresolved: draw nothing, never a guess
|
||||
DesignSketchTool::MateConnectorGlyph g;
|
||||
g.origin = fr.origin;
|
||||
g.x = fr.x;
|
||||
g.y = fr.y;
|
||||
const auto it = role_by_feature.find(int(i));
|
||||
g.role = (ordinal == cs_b) ? 2 : (ordinal == cs_a ? 1
|
||||
: (it != role_by_feature.end() ? it->second : 0));
|
||||
// A face-only connector whose face gave no usable in-plane edge fell back to the hint; that
|
||||
// is the case the glyph has to confess rather than absorb.
|
||||
g.roll_undefined = (f.coordsys_type == CoordSysType::FaceAndDirection
|
||||
&& f.coordsys_edge < 0);
|
||||
out.push_back(g);
|
||||
}
|
||||
m_viewport->set_mate_connectors(std::move(out));
|
||||
}
|
||||
|
||||
void DesignPanel::update_datum_gizmo()
|
||||
|
||||
Reference in New Issue
Block a user