diff --git a/draw.cpp b/draw.cpp index c811ab5..6992c9b 100644 --- a/draw.cpp +++ b/draw.cpp @@ -227,14 +227,9 @@ void GraphicsWindow::HitTestMakeSelection(Point2d mp) { // Faces, from the triangle mesh; these are lowest priority if(s.constraint.v == 0 && s.entity.v == 0 && showShaded && showFaces) { - SMesh *m; - Group *g = SK.GetGroup(activeGroup), - *pg = g->RunningMeshGroup(); - if(pg && g->thisMesh.IsEmpty() && g->thisShell.IsEmpty()) { - m = &(pg->displayMesh); - } else { - m = &(g->displayMesh); - } + Group *g = SK.GetGroup(activeGroup); + SMesh *m = &(g->displayMesh); + DWORD v = m->FirstIntersectionWith(mp); if(v) { s.entity.v = v; diff --git a/groupmesh.cpp b/groupmesh.cpp index 0ffdbad..4d000ae 100644 --- a/groupmesh.cpp +++ b/groupmesh.cpp @@ -312,23 +312,50 @@ void Group::GenerateDisplayItems(void) { // to find the emphasized edges for a mesh), so we will run it only // if its inputs have changed. if(displayDirty) { - displayMesh.Clear(); - runningShell.TriangulateInto(&displayMesh); - STriangle *tr; - for(tr = runningMesh.l.First(); tr; tr = runningMesh.l.NextAfter(tr)) { - STriangle trn = *tr; - Vector n = trn.Normal(); - trn.an = n; - trn.bn = n; - trn.cn = n; - displayMesh.AddTriangle(&trn); - } + Group *pg = RunningMeshGroup(); + if(pg && thisMesh.IsEmpty() && thisShell.IsEmpty()) { + // We don't contribute any new solid model in this group, so our + // display items are identical to the previous group's; which means + // that we can just display those, and stop ourselves from + // recalculating for those every time we get a change in this group. + // + // Note that this can end up recursing multiple times (if multiple + // groups that contribute no solid model exist in sequence), but + // that's okay. + pg->GenerateDisplayItems(); - displayEdges.Clear(); + displayMesh.Clear(); + displayMesh.MakeFromCopyOf(&(pg->displayMesh)); - if(SS.GW.showEdges) { - runningShell.MakeEdgesInto(&displayEdges); - runningMesh.MakeEmphasizedEdgesInto(&displayEdges); + displayEdges.Clear(); + if(SS.GW.showEdges) { + SEdge *se; + SEdgeList *src = &(pg->displayEdges); + for(se = src->l.First(); se; se = src->l.NextAfter(se)) { + displayEdges.l.Add(se); + } + } + } else { + // We do contribute new solid model, so we have to triangulate the + // shell, and edge-find the mesh. + displayMesh.Clear(); + runningShell.TriangulateInto(&displayMesh); + STriangle *t; + for(t = runningMesh.l.First(); t; t = runningMesh.l.NextAfter(t)) { + STriangle trn = *t; + Vector n = trn.Normal(); + trn.an = n; + trn.bn = n; + trn.cn = n; + displayMesh.AddTriangle(&trn); + } + + displayEdges.Clear(); + + if(SS.GW.showEdges) { + runningShell.MakeEdgesInto(&displayEdges); + runningMesh.MakeEmphasizedEdgesInto(&displayEdges); + } } displayDirty = false; @@ -397,20 +424,8 @@ void Group::Draw(void) { // can control this stuff independently, with show/hide solids, edges, // mesh, etc. - // If this changes then make sure to also do the face selection off the - // correct mesh, in draw.cpp. - Group *pg = RunningMeshGroup(); - if(pg && thisMesh.IsEmpty() && thisShell.IsEmpty()) { - // We don't contribute any new solid model in this group, so our - // display items are identical to the previous group's; which means - // that we can just display those, and stop ourselves from - // recalculating for those every time we get a change in this group. - pg->GenerateDisplayItems(); - pg->DrawDisplayItems(type); - } else { - GenerateDisplayItems(); - DrawDisplayItems(type); - } + GenerateDisplayItems(); + DrawDisplayItems(type); if(!SS.checkClosedContour) return; diff --git a/wishlist.txt b/wishlist.txt index 733f588..95630ab 100644 --- a/wishlist.txt +++ b/wishlist.txt @@ -1,13 +1,14 @@ multi-drag +copy and paste +wireframe export +import mirrored ----- some kind of import filled contours for export -wireframe export faster triangulation interpolating splines -copy and paste loop detection IGES export incremental regen of entities