Generate additional edges wherever a front- and back-facing

triangle join. And add controls to show and hide the solid model
edges (independently of the shaded mesh), and to suppress the
shaded triangles from SVG/EPS output.

[git-p4: depot-paths = "//depot/solvespace/": change = 1932]
This commit is contained in:
Jonathan Westhues 2009-03-17 20:26:04 -08:00
parent 1a845c3432
commit d4b842a242
10 changed files with 115 additions and 18 deletions

View File

@ -115,6 +115,14 @@ void SolveSpace::ExportViewTo(char *filename) {
sm = &((SS.GetGroup(SS.GW.activeGroup))->runningMesh);
}
if(SS.GW.showEdges) {
SEdgeList *emph = &((SS.GetGroup(SS.GW.activeGroup))->emphEdges);
SEdge *se;
for(se = emph->l.First(); se; se = emph->l.NextAfter(se)) {
edges.AddEdge(se->a, se->b);
}
}
Vector u = SS.GW.projRight,
v = SS.GW.projUp,
n = u.Cross(v),
@ -212,6 +220,13 @@ void SolveSpace::ExportLinesAndMesh(SEdgeList *sel, SMesh *sm,
ZERO(&hlrd);
if(sm && !SS.GW.showHdnLines) {
SKdNode *root = SKdNode::From(&smp);
// Generate the edges where a curved surface turns from front-facing
// to back-facing.
if(SS.GW.showEdges) {
root->MakeTurningEdgesInto(sel);
}
root->ClearTags();
int cnt = 1234;
@ -306,7 +321,7 @@ void VectorFileWriter::Output(SEdgeList *sel, SMesh *sm) {
}
StartFile();
if(sm) {
if(sm && SS.exportShadedTriangles) {
for(tr = sm->l.First(); tr; tr = sm->l.NextAfter(tr)) {
Triangle(tr);
}

View File

@ -144,6 +144,7 @@ void GraphicsWindow::Init(void) {
showConstraints = true;
showHdnLines = false;
showShaded = true;
showEdges = true;
showMesh = false;
showTextWindow = true;

View File

@ -253,9 +253,7 @@ done:
runningMesh.Clear();
runningShell.TriangulateInto(&runningMesh);
emphEdges.Clear();
if(h.v == SS.GW.activeGroup.v && SS.edgeColor != 0) {
runningShell.MakeEdgesInto(&emphEdges);
}
runningShell.MakeEdgesInto(&emphEdges);
}
SShell *Group::PreviousGroupShell(void) {
@ -298,7 +296,8 @@ void Group::Draw(void) {
glEnable(GL_LIGHTING);
glxFillMesh(specColor, &runningMesh, mh, ms1, ms2);
glDisable(GL_LIGHTING);
}
if(SS.GW.showEdges) {
glLineWidth(1);
glxDepthRangeOffset(2);
glxColor3d(REDf (SS.edgeColor),

View File

@ -476,19 +476,21 @@ void SKdNode::MakeMeshInto(SMesh *m) {
}
}
void SKdNode::FindEdgeOn(Vector a, Vector b, int *n, int cnt, bool *inter) {
void SKdNode::FindEdgeOn(Vector a, Vector b, int *n, int cnt,
bool *inter, bool *fwd)
{
if(gt && lt) {
double ac = a.Element(which),
bc = b.Element(which);
if(ac < c + KDTREE_EPS ||
bc < c + KDTREE_EPS)
{
lt->FindEdgeOn(a, b, n, cnt, inter);
lt->FindEdgeOn(a, b, n, cnt, inter, fwd);
}
if(ac > c - KDTREE_EPS ||
bc > c - KDTREE_EPS)
{
gt->FindEdgeOn(a, b, n, cnt, inter);
gt->FindEdgeOn(a, b, n, cnt, inter, fwd);
}
} else {
STriangleLl *ll;
@ -503,6 +505,12 @@ void SKdNode::FindEdgeOn(Vector a, Vector b, int *n, int cnt, bool *inter) {
(a.Equals(tr->a) && b.Equals(tr->c)))
{
(*n)++;
// Record whether this triangle is front- or back-facing.
if(tr->Normal().z > LENGTH_EPS) {
*fwd = true;
} else {
*fwd = false;
}
} else if(((a.Equals(tr->a) && b.Equals(tr->b)) ||
(a.Equals(tr->b) && b.Equals(tr->c)) ||
(a.Equals(tr->c) && b.Equals(tr->a))))
@ -688,8 +696,8 @@ void SKdNode::MakeNakedEdgesInto(SEdgeList *sel, bool *inter, bool *leaky) {
Vector b = (j == 0) ? tr->b : ((j == 1) ? tr->c : tr->a);
int n = 0, nOther = 0;
bool thisIntersects = false;
FindEdgeOn(a, b, &n, cnt, &thisIntersects);
bool thisIntersects = false, fwd;
FindEdgeOn(a, b, &n, cnt, &thisIntersects, &fwd);
if(n != 1) {
sel->AddEdge(a, b);
if(leaky) *leaky = true;
@ -706,3 +714,35 @@ void SKdNode::MakeNakedEdgesInto(SEdgeList *sel, bool *inter, bool *leaky) {
m.Clear();
}
void SKdNode::MakeTurningEdgesInto(SEdgeList *sel) {
SMesh m;
ZERO(&m);
ClearTags();
MakeMeshInto(&m);
int cnt = 1234;
int i, j;
for(i = 0; i < m.l.n; i++) {
STriangle *tr = &(m.l.elem[i]);
if(tr->Normal().z > LENGTH_EPS) continue;
// So this is a back-facing triangle
for(j = 0; j < 3; j++) {
Vector a = (j == 0) ? tr->a : ((j == 1) ? tr->b : tr->c);
Vector b = (j == 0) ? tr->b : ((j == 1) ? tr->c : tr->a);
int n = 0;
bool inter, fwd;
FindEdgeOn(a, b, &n, cnt, &inter, &fwd);
if(n == 1) {
// and its neighbour is front-facing, so generate the edge.
if(fwd) sel->AddEdge(a, b);
}
cnt++;
}
}
m.Clear();
}

View File

@ -222,8 +222,10 @@ public:
void MakeMeshInto(SMesh *m);
void ClearTags(void);
void FindEdgeOn(Vector a, Vector b, int *n, int cnt, bool *inter);
void FindEdgeOn(Vector a, Vector b, int *n, int cnt,
bool *inter, bool *fwd);
void MakeNakedEdgesInto(SEdgeList *sel, bool *inter=NULL, bool *leaky=NULL);
void MakeTurningEdgesInto(SEdgeList *sel);
void OcclusionTestLine(SEdge orig, SEdgeList *sel, int cnt);
void SplitLinesAgainstTriangle(SEdgeList *sel, STriangle *tr);

View File

@ -54,6 +54,10 @@ void SolveSpace::Init(char *cmdLine) {
exportOffset = CnfThawFloat(0.0f, "ExportOffset");
// Draw back faces of triangles (when mesh is leaky/self-intersecting)
drawBackFaces = CnfThawDWORD(1, "DrawBackFaces");
// Export shaded triangles in a 2d view
exportShadedTriangles = CnfThawDWORD(1, "ExportShadedTriangles");
// Export exact curves (instead of pwl) when possible
exportExactCurves = CnfThawDWORD(0, "ExportExactCurves");
// Show toolbar in the graphics window
showToolbar = CnfThawDWORD(1, "ShowToolbar");
// Recent files menus
@ -118,6 +122,10 @@ void SolveSpace::Exit(void) {
CnfFreezeFloat(exportOffset, "ExportOffset");
// Draw back faces of triangles (when mesh is leaky/self-intersecting)
CnfFreezeDWORD(drawBackFaces, "DrawBackFaces");
// Export shaded triangles in a 2d view
CnfFreezeDWORD(exportShadedTriangles, "ExportShadedTriangles");
// Export exact curves (instead of pwl) when possible
CnfFreezeDWORD(exportExactCurves, "ExportExactCurves");
// Show toolbar in the graphics window
CnfFreezeDWORD(showToolbar, "ShowToolbar");

View File

@ -444,6 +444,8 @@ public:
float exportOffset;
int drawBackFaces;
int showToolbar;
int exportShadedTriangles;
int exportExactCurves;
int CircleSides(double r);
typedef enum {

View File

@ -36,12 +36,14 @@ hs(SS.GW.showConstraints), (DWORD)(&SS.GW.showConstraints), &(SS.GW.ToggleBool)
);
Printf(false, "%Bt%Ft "
"%Fp%Ll%D%fshaded%E "
"%Fp%Ll%D%ffaces%E "
"%Fp%Ll%D%fedges%E "
"%Fp%Ll%D%fmesh%E "
"%Fp%Ll%D%fhidden-lines%E",
"%Fp%Ll%D%ffaces%E "
"%Fp%Ll%D%fhidden-lns%E",
hs(SS.GW.showShaded), (DWORD)(&SS.GW.showShaded), &(SS.GW.ToggleBool),
hs(SS.GW.showFaces), (DWORD)(&SS.GW.showFaces), &(SS.GW.ToggleBool),
hs(SS.GW.showEdges), (DWORD)(&SS.GW.showEdges), &(SS.GW.ToggleBool),
hs(SS.GW.showMesh), (DWORD)(&SS.GW.showMesh), &(SS.GW.ToggleBool),
hs(SS.GW.showFaces), (DWORD)(&SS.GW.showFaces), &(SS.GW.ToggleBool),
hs(SS.GW.showHdnLines), (DWORD)(&SS.GW.showHdnLines), &(SS.GW.ToggleBool)
);
}
@ -607,6 +609,14 @@ void TextWindow::ScreenChangeBackFaces(int link, DWORD v) {
SS.drawBackFaces = !SS.drawBackFaces;
InvalidateGraphics();
}
void TextWindow::ScreenChangeShadedTriangles(int link, DWORD v) {
SS.exportShadedTriangles = !SS.exportShadedTriangles;
InvalidateGraphics();
}
void TextWindow::ScreenChangeExactCurves(int link, DWORD v) {
SS.exportExactCurves = !SS.exportExactCurves;
InvalidateGraphics();
}
void TextWindow::ShowConfiguration(void) {
int i;
Printf(true, "%Ft material color-(r, g, b)");
@ -633,7 +643,7 @@ void TextWindow::ShowConfiguration(void) {
}
Printf(false, "");
Printf(false, "%Ft edge color r,g,b (0,0,0 for no edges)%E");
Printf(false, "%Ft edge color r,g,b%E");
Printf(false, "%Ba %@, %@, %@ %Fl%Ll%f%D[change]%E",
REDf(SS.edgeColor), GREENf(SS.edgeColor), BLUEf(SS.edgeColor),
&ScreenChangeEdgeColor, 0);
@ -665,6 +675,24 @@ void TextWindow::ShowConfiguration(void) {
(double)SS.exportOffset,
&ScreenChangeExportOffset, 0);
Printf(false, "");
Printf(false, "%Ft export shaded 2d triangles: "
"%Fh%f%Ll%s%E%Fs%s%E / %Fh%f%Ll%s%E%Fs%s%E",
&ScreenChangeShadedTriangles,
(SS.exportShadedTriangles ? "" : "yes"),
(SS.exportShadedTriangles ? "yes" : ""),
&ScreenChangeShadedTriangles,
(!SS.exportShadedTriangles ? "" : "no"),
(!SS.exportShadedTriangles ? "no" : ""));
Printf(false, "%Ft export exact curves in DXF: "
"%Fh%f%Ll%s%E%Fs%s%E / %Fh%f%Ll%s%E%Fs%s%E",
&ScreenChangeExactCurves,
(SS.exportExactCurves ? "" : "yes"),
(SS.exportExactCurves ? "yes" : ""),
&ScreenChangeExactCurves,
(!SS.exportExactCurves ? "" : "no"),
(!SS.exportExactCurves ? "no" : ""));
Printf(false, "");
Printf(false, "%Ft draw back faces: "
"%Fh%f%Ll%s%E%Fs%s%E / %Fh%f%Ll%s%E%Fs%s%E",

3
ui.h
View File

@ -145,6 +145,8 @@ public:
static void ScreenGoToWebsite(int link, DWORD v);
static void ScreenChangeBackFaces(int link, DWORD v);
static void ScreenChangeExactCurves(int link, DWORD v);
static void ScreenChangeShadedTriangles(int link, DWORD v);
static void ScreenStepDimSteps(int link, DWORD v);
static void ScreenStepDimFinish(int link, DWORD v);
@ -405,6 +407,7 @@ public:
bool showConstraints;
bool showTextWindow;
bool showShaded;
bool showEdges;
bool showFaces;
bool showMesh;
bool showHdnLines;

View File

@ -2,15 +2,14 @@
marching algorithm for surface intersection
surfaces of revolution (lathed)
cylinder-line special cases
exact boundaries when near pwl trim
boundary avoidance when casting ray for point-in-shell
tangent intersections
short pwl edge avoidance
exact curve export (at least for dxf)
hidden line removal from mesh
line styles (color, thickness)
assembly
-----
line styles (color, thickness)
loop detection
incremental regen of entities?
IGES and STEP export