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:
parent
9b8f32dad7
commit
274005c02c
2
draw.cpp
2
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
|
// 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();
|
||||||
|
13
export.cpp
13
export.cpp
@ -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();
|
||||||
}
|
}
|
||||||
|
25
mesh.cpp
25
mesh.cpp
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user