Add a separate display mesh and edge list; so if we're working with
a mesh than that's a copy, and if we're working with a shell then it's the shell's triangulation. [git-p4: depot-paths = "//depot/solvespace/": change = 1957]
This commit is contained in:
parent
e70bb37061
commit
ddf9364257
2
draw.cpp
2
draw.cpp
|
@ -868,7 +868,7 @@ void GraphicsWindow::HitTestMakeSelection(Point2d mp) {
|
||||||
|
|
||||||
// Faces, from the triangle mesh; these are lowest priority
|
// Faces, from the triangle mesh; these are lowest priority
|
||||||
if(s.constraint.v == 0 && s.entity.v == 0 && showShaded && showFaces) {
|
if(s.constraint.v == 0 && s.entity.v == 0 && showShaded && showFaces) {
|
||||||
SMesh *m = &((SK.GetGroup(activeGroup))->runningMesh);
|
SMesh *m = &((SK.GetGroup(activeGroup))->displayMesh);
|
||||||
DWORD v = m->FirstIntersectionWith(mp);
|
DWORD v = m->FirstIntersectionWith(mp);
|
||||||
if(v) {
|
if(v) {
|
||||||
s.entity.v = v;
|
s.entity.v = v;
|
||||||
|
|
13
export.cpp
13
export.cpp
|
@ -6,7 +6,8 @@ void SolveSpace::ExportSectionTo(char *filename) {
|
||||||
gn = gn.WithMagnitude(1);
|
gn = gn.WithMagnitude(1);
|
||||||
|
|
||||||
Group *g = SK.GetGroup(SS.GW.activeGroup);
|
Group *g = SK.GetGroup(SS.GW.activeGroup);
|
||||||
if(g->runningMesh.l.n == 0) {
|
g->GenerateDisplayItems();
|
||||||
|
if(g->displayMesh.l.n == 0) {
|
||||||
Error("No solid model present; draw one with extrudes and revolves, "
|
Error("No solid model present; draw one with extrudes and revolves, "
|
||||||
"or use Export 2d View to export bare lines and curves.");
|
"or use Export 2d View to export bare lines and curves.");
|
||||||
return;
|
return;
|
||||||
|
@ -95,7 +96,9 @@ void SolveSpace::ExportViewTo(char *filename) {
|
||||||
|
|
||||||
SMesh *sm = NULL;
|
SMesh *sm = NULL;
|
||||||
if(SS.GW.showShaded) {
|
if(SS.GW.showShaded) {
|
||||||
sm = &((SK.GetGroup(SS.GW.activeGroup))->runningMesh);
|
Group *g = SK.GetGroup(SS.GW.activeGroup);
|
||||||
|
g->GenerateDisplayItems();
|
||||||
|
sm = &(g->displayMesh);
|
||||||
}
|
}
|
||||||
if(sm->l.n == 0) {
|
if(sm->l.n == 0) {
|
||||||
sm = NULL;
|
sm = NULL;
|
||||||
|
@ -119,7 +122,9 @@ void SolveSpace::ExportViewTo(char *filename) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(SS.GW.showEdges) {
|
if(SS.GW.showEdges) {
|
||||||
SEdgeList *selr = &((SK.GetGroup(SS.GW.activeGroup))->runningEdges);
|
Group *g = SK.GetGroup(SS.GW.activeGroup);
|
||||||
|
g->GenerateDisplayItems();
|
||||||
|
SEdgeList *selr = &(g->displayEdges);
|
||||||
SEdge *se;
|
SEdge *se;
|
||||||
for(se = selr->l.First(); se; se = selr->l.NextAfter(se)) {
|
for(se = selr->l.First(); se; se = selr->l.NextAfter(se)) {
|
||||||
edges.AddEdge(se->a, se->b);
|
edges.AddEdge(se->a, se->b);
|
||||||
|
@ -973,7 +978,7 @@ void HpglFileWriter::FinishAndCloseFile(void) {
|
||||||
// not self-intersecting, so not much to do.
|
// not self-intersecting, so not much to do.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void SolveSpace::ExportMeshTo(char *filename) {
|
void SolveSpace::ExportMeshTo(char *filename) {
|
||||||
SMesh *m = &(SK.GetGroup(SS.GW.activeGroup)->runningMesh);
|
SMesh *m = &(SK.GetGroup(SS.GW.activeGroup)->displayMesh);
|
||||||
if(m->l.n == 0) {
|
if(m->l.n == 0) {
|
||||||
Error("Active group mesh is empty; nothing to export.");
|
Error("Active group mesh is empty; nothing to export.");
|
||||||
return;
|
return;
|
||||||
|
|
4
file.cpp
4
file.cpp
|
@ -78,6 +78,7 @@ const SolveSpace::SaveTable SolveSpace::SAVED[] = {
|
||||||
{ 'g', "Group.subtype", 'd', &(SS.sv.g.subtype) },
|
{ 'g', "Group.subtype", 'd', &(SS.sv.g.subtype) },
|
||||||
{ 'g', "Group.skipFirst", 'b', &(SS.sv.g.skipFirst) },
|
{ 'g', "Group.skipFirst", 'b', &(SS.sv.g.skipFirst) },
|
||||||
{ 'g', "Group.meshCombine", 'd', &(SS.sv.g.meshCombine) },
|
{ 'g', "Group.meshCombine", 'd', &(SS.sv.g.meshCombine) },
|
||||||
|
{ 'g', "Group.forceToMesh", 'd', &(SS.sv.g.forceToMesh) },
|
||||||
{ 'g', "Group.predef.q.w", 'f', &(SS.sv.g.predef.q.w) },
|
{ 'g', "Group.predef.q.w", 'f', &(SS.sv.g.predef.q.w) },
|
||||||
{ 'g', "Group.predef.q.vx", 'f', &(SS.sv.g.predef.q.vx) },
|
{ 'g', "Group.predef.q.vx", 'f', &(SS.sv.g.predef.q.vx) },
|
||||||
{ 'g', "Group.predef.q.vy", 'f', &(SS.sv.g.predef.q.vy) },
|
{ 'g', "Group.predef.q.vy", 'f', &(SS.sv.g.predef.q.vy) },
|
||||||
|
@ -235,6 +236,9 @@ bool SolveSpace::SaveToFile(char *filename) {
|
||||||
fprintf(fh, "AddConstraint\n\n");
|
fprintf(fh, "AddConstraint\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A group will have either a mesh or a shell, but not both; but the code
|
||||||
|
// to print either of those just does nothing if the mesh/shell is empty.
|
||||||
|
|
||||||
SMesh *m = &(SK.group.elem[SK.group.n-1].runningMesh);
|
SMesh *m = &(SK.group.elem[SK.group.n-1].runningMesh);
|
||||||
for(i = 0; i < m->l.n; i++) {
|
for(i = 0; i < m->l.n; i++) {
|
||||||
STriangle *tr = &(m->l.elem[i]);
|
STriangle *tr = &(m->l.elem[i]);
|
||||||
|
|
|
@ -290,9 +290,11 @@ void GraphicsWindow::LoopOverPoints(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Group *g = SK.GetGroup(activeGroup);
|
Group *g = SK.GetGroup(activeGroup);
|
||||||
for(i = 0; i < g->runningMesh.l.n; i++) {
|
g->GenerateDisplayItems();
|
||||||
STriangle *tr = &(g->runningMesh.l.elem[i]);
|
for(i = 0; i < g->displayMesh.l.n; i++) {
|
||||||
|
STriangle *tr = &(g->displayMesh.l.elem[i]);
|
||||||
HandlePointForZoomToFit(tr->a, pmax, pmin, wmin, div);
|
HandlePointForZoomToFit(tr->a, pmax, pmin, wmin, div);
|
||||||
HandlePointForZoomToFit(tr->b, pmax, pmin, wmin, div);
|
HandlePointForZoomToFit(tr->b, pmax, pmin, wmin, div);
|
||||||
HandlePointForZoomToFit(tr->c, pmax, pmin, wmin, div);
|
HandlePointForZoomToFit(tr->c, pmax, pmin, wmin, div);
|
||||||
|
|
|
@ -238,8 +238,8 @@ void Group::GenerateShellAndMesh(void) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
// So our group's mesh appears in thisMesh. Combine this with the previous
|
// So our group's shell appears in thisShell. Combine this with the
|
||||||
// group's mesh, using the requested operation.
|
// previous group's shell, using the requested operation.
|
||||||
SShell *a = PreviousGroupShell();
|
SShell *a = PreviousGroupShell();
|
||||||
if(meshCombine == COMBINE_AS_UNION) {
|
if(meshCombine == COMBINE_AS_UNION) {
|
||||||
runningShell.MakeFromUnionOf(a, &thisShell);
|
runningShell.MakeFromUnionOf(a, &thisShell);
|
||||||
|
@ -250,10 +250,17 @@ void Group::GenerateShellAndMesh(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
runningMesh.Clear();
|
displayDirty = true;
|
||||||
runningShell.TriangulateInto(&runningMesh);
|
}
|
||||||
runningEdges.Clear();
|
|
||||||
runningShell.MakeEdgesInto(&runningEdges);
|
void Group::GenerateDisplayItems(void) {
|
||||||
|
if(displayDirty) {
|
||||||
|
displayMesh.Clear();
|
||||||
|
runningShell.TriangulateInto(&displayMesh);
|
||||||
|
displayEdges.Clear();
|
||||||
|
runningShell.MakeEdgesInto(&displayEdges);
|
||||||
|
displayDirty = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SShell *Group::PreviousGroupShell(void) {
|
SShell *Group::PreviousGroupShell(void) {
|
||||||
|
@ -267,8 +274,12 @@ SShell *Group::PreviousGroupShell(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Group::Draw(void) {
|
void Group::Draw(void) {
|
||||||
// Show this even if the group is not visible. It's already possible
|
// Everything here gets drawn whether or not the group is hidden; we
|
||||||
// to show or hide just this with the "show solids" flag.
|
// can control this stuff independently, with show/hide solids, edges,
|
||||||
|
// mesh, etc.
|
||||||
|
|
||||||
|
// Triangulate the shells if necessary.
|
||||||
|
GenerateDisplayItems();
|
||||||
|
|
||||||
int specColor;
|
int specColor;
|
||||||
if(type == DRAWING_3D || type == DRAWING_WORKPLANE) {
|
if(type == DRAWING_3D || type == DRAWING_WORKPLANE) {
|
||||||
|
@ -294,7 +305,7 @@ void Group::Draw(void) {
|
||||||
|
|
||||||
if(SS.GW.showShaded) {
|
if(SS.GW.showShaded) {
|
||||||
glEnable(GL_LIGHTING);
|
glEnable(GL_LIGHTING);
|
||||||
glxFillMesh(specColor, &runningMesh, mh, ms1, ms2);
|
glxFillMesh(specColor, &displayMesh, mh, ms1, ms2);
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
}
|
}
|
||||||
if(SS.GW.showEdges) {
|
if(SS.GW.showEdges) {
|
||||||
|
@ -303,10 +314,10 @@ void Group::Draw(void) {
|
||||||
glxColor3d(REDf (SS.edgeColor),
|
glxColor3d(REDf (SS.edgeColor),
|
||||||
GREENf(SS.edgeColor),
|
GREENf(SS.edgeColor),
|
||||||
BLUEf (SS.edgeColor));
|
BLUEf (SS.edgeColor));
|
||||||
glxDrawEdges(&runningEdges);
|
glxDrawEdges(&displayEdges);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(SS.GW.showMesh) glxDebugMesh(&runningMesh);
|
if(SS.GW.showMesh) glxDebugMesh(&displayMesh);
|
||||||
|
|
||||||
// And finally show the polygons too
|
// And finally show the polygons too
|
||||||
if(!SS.GW.showShaded) return;
|
if(!SS.GW.showShaded) return;
|
||||||
|
|
9
sketch.h
9
sketch.h
|
@ -148,14 +148,20 @@ public:
|
||||||
SShell thisShell;
|
SShell thisShell;
|
||||||
SShell runningShell;
|
SShell runningShell;
|
||||||
|
|
||||||
|
SMesh thisMesh;
|
||||||
SMesh runningMesh;
|
SMesh runningMesh;
|
||||||
SEdgeList runningEdges;
|
|
||||||
|
bool displayDirty;
|
||||||
|
SMesh displayMesh;
|
||||||
|
SEdgeList displayEdges;
|
||||||
|
|
||||||
static const int COMBINE_AS_UNION = 0;
|
static const int COMBINE_AS_UNION = 0;
|
||||||
static const int COMBINE_AS_DIFFERENCE = 1;
|
static const int COMBINE_AS_DIFFERENCE = 1;
|
||||||
static const int COMBINE_AS_ASSEMBLE = 2;
|
static const int COMBINE_AS_ASSEMBLE = 2;
|
||||||
int meshCombine;
|
int meshCombine;
|
||||||
|
|
||||||
|
bool forceToMesh;
|
||||||
|
|
||||||
IdList<EntityMap,EntityId> remap;
|
IdList<EntityMap,EntityId> remap;
|
||||||
static const int REMAP_PRIME = 19477;
|
static const int REMAP_PRIME = 19477;
|
||||||
int remapCache[REMAP_PRIME];
|
int remapCache[REMAP_PRIME];
|
||||||
|
@ -203,6 +209,7 @@ public:
|
||||||
// And the mesh stuff
|
// And the mesh stuff
|
||||||
SShell *PreviousGroupShell(void);
|
SShell *PreviousGroupShell(void);
|
||||||
void GenerateShellForStepAndRepeat(void);
|
void GenerateShellForStepAndRepeat(void);
|
||||||
|
void GenerateDisplayItems(void);
|
||||||
void GenerateShellAndMesh(void);
|
void GenerateShellAndMesh(void);
|
||||||
void Draw(void);
|
void Draw(void);
|
||||||
|
|
||||||
|
|
|
@ -417,7 +417,7 @@ void SolveSpace::MenuAnalyze(int id) {
|
||||||
case GraphicsWindow::MNU_NAKED_EDGES: {
|
case GraphicsWindow::MNU_NAKED_EDGES: {
|
||||||
SS.nakedEdges.Clear();
|
SS.nakedEdges.Clear();
|
||||||
|
|
||||||
SMesh *m = &(SK.GetGroup(SS.GW.activeGroup)->runningMesh);
|
SMesh *m = &(SK.GetGroup(SS.GW.activeGroup)->displayMesh);
|
||||||
SKdNode *root = SKdNode::From(m);
|
SKdNode *root = SKdNode::From(m);
|
||||||
bool inters, leaks;
|
bool inters, leaks;
|
||||||
root->MakeNakedEdgesInto(&(SS.nakedEdges), &inters, &leaks);
|
root->MakeNakedEdgesInto(&(SS.nakedEdges), &inters, &leaks);
|
||||||
|
@ -441,7 +441,7 @@ void SolveSpace::MenuAnalyze(int id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case GraphicsWindow::MNU_VOLUME: {
|
case GraphicsWindow::MNU_VOLUME: {
|
||||||
SMesh *m = &(SK.GetGroup(SS.GW.activeGroup)->runningMesh);
|
SMesh *m = &(SK.GetGroup(SS.GW.activeGroup)->displayMesh);
|
||||||
|
|
||||||
double vol = 0;
|
double vol = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -654,7 +654,7 @@ void TextWindow::ShowConfiguration(void) {
|
||||||
Printf(false, "%Ba %2 %Fl%Ll%f%D[change]%E; now %d triangles",
|
Printf(false, "%Ba %2 %Fl%Ll%f%D[change]%E; now %d triangles",
|
||||||
SS.chordTol,
|
SS.chordTol,
|
||||||
&ScreenChangeChordTolerance, 0,
|
&ScreenChangeChordTolerance, 0,
|
||||||
SK.GetGroup(SS.GW.activeGroup)->runningMesh.l.n);
|
SK.GetGroup(SS.GW.activeGroup)->displayMesh.l.n);
|
||||||
Printf(false, "%Ft max piecewise linear segments%E");
|
Printf(false, "%Ft max piecewise linear segments%E");
|
||||||
Printf(false, "%Ba %d %Fl%Ll%f[change]%E",
|
Printf(false, "%Ba %d %Fl%Ll%f[change]%E",
|
||||||
SS.maxSegments,
|
SS.maxSegments,
|
||||||
|
|
|
@ -50,10 +50,12 @@ void SolveSpace::PushFromCurrentOnto(UndoStack *uk) {
|
||||||
ZERO(&(dest.poly));
|
ZERO(&(dest.poly));
|
||||||
ZERO(&(dest.bezierLoopSet));
|
ZERO(&(dest.bezierLoopSet));
|
||||||
ZERO(&(dest.polyError));
|
ZERO(&(dest.polyError));
|
||||||
|
ZERO(&(dest.thisMesh));
|
||||||
ZERO(&(dest.runningMesh));
|
ZERO(&(dest.runningMesh));
|
||||||
ZERO(&(dest.thisShell));
|
ZERO(&(dest.thisShell));
|
||||||
ZERO(&(dest.runningShell));
|
ZERO(&(dest.runningShell));
|
||||||
ZERO(&(dest.runningEdges));
|
ZERO(&(dest.displayMesh));
|
||||||
|
ZERO(&(dest.displayEdges));
|
||||||
|
|
||||||
ZERO(&(dest.remap));
|
ZERO(&(dest.remap));
|
||||||
src->remap.DeepCopyInto(&(dest.remap));
|
src->remap.DeepCopyInto(&(dest.remap));
|
||||||
|
@ -93,10 +95,12 @@ void SolveSpace::PopOntoCurrentFrom(UndoStack *uk) {
|
||||||
Group *g = &(SK.group.elem[i]);
|
Group *g = &(SK.group.elem[i]);
|
||||||
g->poly.Clear();
|
g->poly.Clear();
|
||||||
g->bezierLoopSet.Clear();
|
g->bezierLoopSet.Clear();
|
||||||
|
g->thisMesh.Clear();
|
||||||
g->runningMesh.Clear();
|
g->runningMesh.Clear();
|
||||||
g->thisShell.Clear();
|
g->thisShell.Clear();
|
||||||
g->runningShell.Clear();
|
g->runningShell.Clear();
|
||||||
g->runningEdges.Clear();
|
g->displayMesh.Clear();
|
||||||
|
g->displayEdges.Clear();
|
||||||
g->remap.Clear();
|
g->remap.Clear();
|
||||||
g->impMesh.Clear();
|
g->impMesh.Clear();
|
||||||
g->impShell.Clear();
|
g->impShell.Clear();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user