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]
This commit is contained in:
Jonathan Westhues 2009-09-21 22:47:11 -08:00
parent 9b8f32dad7
commit 274005c02c
4 changed files with 28 additions and 17 deletions

View File

@ -281,7 +281,7 @@ void GraphicsWindow::SpaceNavigatorMoved(double tx, double ty, double tz,
// but it's given with respect to screen projection frame // but it's given with respect to screen projection frame
aa = aa.ScaleOutOfCsys(projRight, projUp, out); aa = aa.ScaleOutOfCsys(projRight, projUp, out);
double aam = aa.Magnitude(); 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. // This can either transform our view, or transform an imported part.
GroupSelection(); GroupSelection();

View File

@ -120,7 +120,7 @@ void SolveSpace::ExportViewTo(char *filename) {
g->GenerateDisplayItems(); g->GenerateDisplayItems();
sm = &(g->displayMesh); sm = &(g->displayMesh);
} }
if(sm->IsEmpty()) { if(sm && sm->IsEmpty()) {
sm = NULL; sm = NULL;
} }
@ -280,10 +280,17 @@ void SolveSpace::ExportLinesAndMesh(SEdgeList *sel, SBezierList *sbl, SMesh *sm,
SEdge *se; SEdge *se;
for(se = sel->l.First(); se; se = sel->l.NextAfter(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; SEdgeList out;
ZERO(&out); ZERO(&out);
// Split the original edge against the mesh // 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); root->OcclusionTestLine(*se, &out, cnt);
// the occlusion test splits unnecessarily; so fix those // the occlusion test splits unnecessarily; so fix those
out.MergeCollinearSegments(se->a, se->b); 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 // And add the results to our output
SEdge *sen; SEdge *sen;
for(sen = out.l.First(); sen; sen = out.l.NextAfter(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(); out.Clear();
} }

View File

@ -630,10 +630,11 @@ void SKdNode::SplitLinesAgainstTriangle(SEdgeList *sel, STriangle *tr) {
Vector tn = tr->Normal().WithMagnitude(1); Vector tn = tr->Normal().WithMagnitude(1);
double td = tn.Dot(tr->a); double td = tn.Dot(tr->a);
// Consider front-facing triangles only // Consider front-facing triangles only.
if(tn.z > LENGTH_EPS) { if(tn.z > LENGTH_EPS) {
// If the edge crosses our triangle's plane, then split into above // 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; SEdge *se;
for(se = sel->l.First(); se; se = sel->l.NextAfter(se)) { for(se = sel->l.First(); se; se = sel->l.NextAfter(se)) {
double da = (se->a).Dot(tn) - td, double da = (se->a).Dot(tn) - td,
@ -644,12 +645,12 @@ void SKdNode::SplitLinesAgainstTriangle(SEdgeList *sel, STriangle *tr) {
Vector m = Vector::AtIntersectionOfPlaneAndLine( Vector m = Vector::AtIntersectionOfPlaneAndLine(
tn, td, tn, td,
se->a, se->b, NULL); se->a, se->b, NULL);
seln.AddEdge(m, se->b); seln.AddEdge(m, se->b, se->auxA);
se->b = m; se->b = m;
} }
} }
for(se = seln.l.First(); se; se = seln.l.NextAfter(se)) { 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(); seln.Clear();
@ -659,10 +660,10 @@ void SKdNode::SplitLinesAgainstTriangle(SEdgeList *sel, STriangle *tr) {
if(pt.Dot(tn) - td > -LENGTH_EPS) { if(pt.Dot(tn) - td > -LENGTH_EPS) {
// Edge is in front of or on our plane (remember, tn.z > 0) // Edge is in front of or on our plane (remember, tn.z > 0)
// so it is exempt from further splitting // so it is exempt from further splitting
se->auxA = 1; se->auxB = 1;
} else { } else {
// Edge is behind our plane, needs further splitting // 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; int i;
for(i = 0; i < 3; i++) { for(i = 0; i < 3; i++) {
for(se = sel->l.First(); se; se = sel->l.NextAfter(se)) { for(se = sel->l.First(); se; se = sel->l.NextAfter(se)) {
if(se->auxA) continue; if(se->auxB) continue;
Point2d ap = (se->a).ProjectXy(), Point2d ap = (se->a).ProjectXy(),
bp = (se->b).ProjectXy(); bp = (se->b).ProjectXy();
@ -696,18 +697,20 @@ void SKdNode::SplitLinesAgainstTriangle(SEdgeList *sel, STriangle *tr) {
double dab = (db - da); double dab = (db - da);
Vector spl = ((se->a).ScaledBy( db/dab)).Plus( Vector spl = ((se->a).ScaledBy( db/dab)).Plus(
(se->b).ScaledBy(-da/dab)); (se->b).ScaledBy(-da/dab));
seln.AddEdge(spl, se->b); seln.AddEdge(spl, se->b, se->auxA);
se->b = spl; se->b = spl;
} }
} }
for(se = seln.l.First(); se; se = seln.l.NextAfter(se)) { 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(); seln.Clear();
} }
for(se = sel->l.First(); se; se = sel->l.NextAfter(se)) { 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 // Lies above or on the triangle plane, so triangle doesn't
// occlude it. // occlude it.
se->tag = 0; se->tag = 0;
@ -929,7 +932,7 @@ void SKdNode::MakeCertainEdgesInto(SEdgeList *sel, int how,
// This triangle is back-facing (or on edge), and // This triangle is back-facing (or on edge), and
// this edge has exactly one mate, and that mate is // this edge has exactly one mate, and that mate is
// front-facing. So this is a turning edge. // front-facing. So this is a turning edge.
sel->AddEdge(a, b); sel->AddEdge(a, b, Style::SOLID_EDGE);
} }
break; break;

View File

@ -79,9 +79,10 @@ bool GraphicsWindow::ToolbarMouseDown(int x, int y) {
x += ((int)width/2); x += ((int)width/2);
y += ((int)height/2); y += ((int)height/2);
int nh; int nh = -1;
bool withinToolbar = ToolbarDrawOrHitTest(x, y, false, &nh); 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++) { for(int i = 0; SS.GW.menu[i].level >= 0; i++) {
if(nh == SS.GW.menu[i].id) { if(nh == SS.GW.menu[i].id) {
(SS.GW.menu[i].fn)((GraphicsWindow::MenuId)SS.GW.menu[i].id); (SS.GW.menu[i].fn)((GraphicsWindow::MenuId)SS.GW.menu[i].id);