From 274005c02cab3184f00db39dcd167c69a2385e50 Mon Sep 17 00:00:00 2001 From: Jonathan Westhues Date: Mon, 21 Sep 2009 22:47:11 -0800 Subject: [PATCH] Make hidden line removal keep all the line styles, and don't apply that to the constraints. And fix two crashing bugs, embarrassing, both chasing null pointers. [git-p4: depot-paths = "//depot/solvespace/": change = 2031] --- draw.cpp | 2 +- export.cpp | 13 ++++++++++--- mesh.cpp | 25 ++++++++++++++----------- toolbar.cpp | 5 +++-- 4 files changed, 28 insertions(+), 17 deletions(-) diff --git a/draw.cpp b/draw.cpp index 73bd6a0..08e2d7e 100644 --- a/draw.cpp +++ b/draw.cpp @@ -281,7 +281,7 @@ void GraphicsWindow::SpaceNavigatorMoved(double tx, double ty, double tz, // but it's given with respect to screen projection frame aa = aa.ScaleOutOfCsys(projRight, projUp, out); double aam = aa.Magnitude(); - aa = aa.WithMagnitude(1); + if(aam != 0.0) aa = aa.WithMagnitude(1); // This can either transform our view, or transform an imported part. GroupSelection(); diff --git a/export.cpp b/export.cpp index bf12d81..bab8996 100644 --- a/export.cpp +++ b/export.cpp @@ -120,7 +120,7 @@ void SolveSpace::ExportViewTo(char *filename) { g->GenerateDisplayItems(); sm = &(g->displayMesh); } - if(sm->IsEmpty()) { + if(sm && sm->IsEmpty()) { sm = NULL; } @@ -280,10 +280,17 @@ void SolveSpace::ExportLinesAndMesh(SEdgeList *sel, SBezierList *sbl, SMesh *sm, SEdge *se; for(se = sel->l.First(); se; se = sel->l.NextAfter(se)) { + if(se->auxA == Style::CONSTRAINT) { + // Constraints should not get hidden line removed; they're + // always on top. + hlrd.AddEdge(se->a, se->b, se->auxA); + continue; + } + SEdgeList out; ZERO(&out); // Split the original edge against the mesh - out.AddEdge(se->a, se->b); + out.AddEdge(se->a, se->b, se->auxA); root->OcclusionTestLine(*se, &out, cnt); // the occlusion test splits unnecessarily; so fix those out.MergeCollinearSegments(se->a, se->b); @@ -291,7 +298,7 @@ void SolveSpace::ExportLinesAndMesh(SEdgeList *sel, SBezierList *sbl, SMesh *sm, // And add the results to our output SEdge *sen; for(sen = out.l.First(); sen; sen = out.l.NextAfter(sen)) { - hlrd.AddEdge(sen->a, sen->b); + hlrd.AddEdge(sen->a, sen->b, sen->auxA); } out.Clear(); } diff --git a/mesh.cpp b/mesh.cpp index 74008fd..51506a0 100644 --- a/mesh.cpp +++ b/mesh.cpp @@ -630,10 +630,11 @@ void SKdNode::SplitLinesAgainstTriangle(SEdgeList *sel, STriangle *tr) { Vector tn = tr->Normal().WithMagnitude(1); double td = tn.Dot(tr->a); - // Consider front-facing triangles only + // Consider front-facing triangles only. if(tn.z > LENGTH_EPS) { // If the edge crosses our triangle's plane, then split into above - // and below parts. + // and below parts. Note that we must preserve auxA, which contains + // the style associated with this line. SEdge *se; for(se = sel->l.First(); se; se = sel->l.NextAfter(se)) { double da = (se->a).Dot(tn) - td, @@ -644,12 +645,12 @@ void SKdNode::SplitLinesAgainstTriangle(SEdgeList *sel, STriangle *tr) { Vector m = Vector::AtIntersectionOfPlaneAndLine( tn, td, se->a, se->b, NULL); - seln.AddEdge(m, se->b); + seln.AddEdge(m, se->b, se->auxA); se->b = m; } } for(se = seln.l.First(); se; se = seln.l.NextAfter(se)) { - sel->AddEdge(se->a, se->b); + sel->AddEdge(se->a, se->b, se->auxA); } seln.Clear(); @@ -659,10 +660,10 @@ void SKdNode::SplitLinesAgainstTriangle(SEdgeList *sel, STriangle *tr) { if(pt.Dot(tn) - td > -LENGTH_EPS) { // Edge is in front of or on our plane (remember, tn.z > 0) // so it is exempt from further splitting - se->auxA = 1; + se->auxB = 1; } else { // Edge is behind our plane, needs further splitting - se->auxA = 0; + se->auxB = 0; } } @@ -684,7 +685,7 @@ void SKdNode::SplitLinesAgainstTriangle(SEdgeList *sel, STriangle *tr) { int i; for(i = 0; i < 3; i++) { for(se = sel->l.First(); se; se = sel->l.NextAfter(se)) { - if(se->auxA) continue; + if(se->auxB) continue; Point2d ap = (se->a).ProjectXy(), bp = (se->b).ProjectXy(); @@ -696,18 +697,20 @@ void SKdNode::SplitLinesAgainstTriangle(SEdgeList *sel, STriangle *tr) { double dab = (db - da); Vector spl = ((se->a).ScaledBy( db/dab)).Plus( (se->b).ScaledBy(-da/dab)); - seln.AddEdge(spl, se->b); + seln.AddEdge(spl, se->b, se->auxA); se->b = spl; } } for(se = seln.l.First(); se; se = seln.l.NextAfter(se)) { - sel->AddEdge(se->a, se->b, 0); + // The split pieces are all behind the triangle, since only + // edges behind the triangle got split. So their auxB is 0. + sel->AddEdge(se->a, se->b, se->auxA, 0); } seln.Clear(); } for(se = sel->l.First(); se; se = sel->l.NextAfter(se)) { - if(se->auxA) { + if(se->auxB) { // Lies above or on the triangle plane, so triangle doesn't // occlude it. se->tag = 0; @@ -929,7 +932,7 @@ void SKdNode::MakeCertainEdgesInto(SEdgeList *sel, int how, // This triangle is back-facing (or on edge), and // this edge has exactly one mate, and that mate is // front-facing. So this is a turning edge. - sel->AddEdge(a, b); + sel->AddEdge(a, b, Style::SOLID_EDGE); } break; diff --git a/toolbar.cpp b/toolbar.cpp index d19f73c..e0969b7 100644 --- a/toolbar.cpp +++ b/toolbar.cpp @@ -79,9 +79,10 @@ bool GraphicsWindow::ToolbarMouseDown(int x, int y) { x += ((int)width/2); y += ((int)height/2); - int nh; + int nh = -1; bool withinToolbar = ToolbarDrawOrHitTest(x, y, false, &nh); - if(withinToolbar) { + // They might have clicked within the toolbar, but not on a button. + if(withinToolbar && nh >= 0) { for(int i = 0; SS.GW.menu[i].level >= 0; i++) { if(nh == SS.GW.menu[i].id) { (SS.GW.menu[i].fn)((GraphicsWindow::MenuId)SS.GW.menu[i].id);