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:
parent
1a845c3432
commit
d4b842a242
17
export.cpp
17
export.cpp
|
@ -115,6 +115,14 @@ void SolveSpace::ExportViewTo(char *filename) {
|
||||||
sm = &((SS.GetGroup(SS.GW.activeGroup))->runningMesh);
|
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,
|
Vector u = SS.GW.projRight,
|
||||||
v = SS.GW.projUp,
|
v = SS.GW.projUp,
|
||||||
n = u.Cross(v),
|
n = u.Cross(v),
|
||||||
|
@ -212,6 +220,13 @@ void SolveSpace::ExportLinesAndMesh(SEdgeList *sel, SMesh *sm,
|
||||||
ZERO(&hlrd);
|
ZERO(&hlrd);
|
||||||
if(sm && !SS.GW.showHdnLines) {
|
if(sm && !SS.GW.showHdnLines) {
|
||||||
SKdNode *root = SKdNode::From(&smp);
|
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();
|
root->ClearTags();
|
||||||
int cnt = 1234;
|
int cnt = 1234;
|
||||||
|
|
||||||
|
@ -306,7 +321,7 @@ void VectorFileWriter::Output(SEdgeList *sel, SMesh *sm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
StartFile();
|
StartFile();
|
||||||
if(sm) {
|
if(sm && SS.exportShadedTriangles) {
|
||||||
for(tr = sm->l.First(); tr; tr = sm->l.NextAfter(tr)) {
|
for(tr = sm->l.First(); tr; tr = sm->l.NextAfter(tr)) {
|
||||||
Triangle(tr);
|
Triangle(tr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,6 +144,7 @@ void GraphicsWindow::Init(void) {
|
||||||
showConstraints = true;
|
showConstraints = true;
|
||||||
showHdnLines = false;
|
showHdnLines = false;
|
||||||
showShaded = true;
|
showShaded = true;
|
||||||
|
showEdges = true;
|
||||||
showMesh = false;
|
showMesh = false;
|
||||||
|
|
||||||
showTextWindow = true;
|
showTextWindow = true;
|
||||||
|
|
|
@ -253,9 +253,7 @@ done:
|
||||||
runningMesh.Clear();
|
runningMesh.Clear();
|
||||||
runningShell.TriangulateInto(&runningMesh);
|
runningShell.TriangulateInto(&runningMesh);
|
||||||
emphEdges.Clear();
|
emphEdges.Clear();
|
||||||
if(h.v == SS.GW.activeGroup.v && SS.edgeColor != 0) {
|
runningShell.MakeEdgesInto(&emphEdges);
|
||||||
runningShell.MakeEdgesInto(&emphEdges);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SShell *Group::PreviousGroupShell(void) {
|
SShell *Group::PreviousGroupShell(void) {
|
||||||
|
@ -298,7 +296,8 @@ void Group::Draw(void) {
|
||||||
glEnable(GL_LIGHTING);
|
glEnable(GL_LIGHTING);
|
||||||
glxFillMesh(specColor, &runningMesh, mh, ms1, ms2);
|
glxFillMesh(specColor, &runningMesh, mh, ms1, ms2);
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
|
}
|
||||||
|
if(SS.GW.showEdges) {
|
||||||
glLineWidth(1);
|
glLineWidth(1);
|
||||||
glxDepthRangeOffset(2);
|
glxDepthRangeOffset(2);
|
||||||
glxColor3d(REDf (SS.edgeColor),
|
glxColor3d(REDf (SS.edgeColor),
|
||||||
|
|
50
mesh.cpp
50
mesh.cpp
|
@ -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) {
|
if(gt && lt) {
|
||||||
double ac = a.Element(which),
|
double ac = a.Element(which),
|
||||||
bc = b.Element(which);
|
bc = b.Element(which);
|
||||||
if(ac < c + KDTREE_EPS ||
|
if(ac < c + KDTREE_EPS ||
|
||||||
bc < 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 ||
|
if(ac > c - KDTREE_EPS ||
|
||||||
bc > c - KDTREE_EPS)
|
bc > c - KDTREE_EPS)
|
||||||
{
|
{
|
||||||
gt->FindEdgeOn(a, b, n, cnt, inter);
|
gt->FindEdgeOn(a, b, n, cnt, inter, fwd);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
STriangleLl *ll;
|
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)))
|
(a.Equals(tr->a) && b.Equals(tr->c)))
|
||||||
{
|
{
|
||||||
(*n)++;
|
(*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)) ||
|
} else if(((a.Equals(tr->a) && b.Equals(tr->b)) ||
|
||||||
(a.Equals(tr->b) && b.Equals(tr->c)) ||
|
(a.Equals(tr->b) && b.Equals(tr->c)) ||
|
||||||
(a.Equals(tr->c) && b.Equals(tr->a))))
|
(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);
|
Vector b = (j == 0) ? tr->b : ((j == 1) ? tr->c : tr->a);
|
||||||
|
|
||||||
int n = 0, nOther = 0;
|
int n = 0, nOther = 0;
|
||||||
bool thisIntersects = false;
|
bool thisIntersects = false, fwd;
|
||||||
FindEdgeOn(a, b, &n, cnt, &thisIntersects);
|
FindEdgeOn(a, b, &n, cnt, &thisIntersects, &fwd);
|
||||||
if(n != 1) {
|
if(n != 1) {
|
||||||
sel->AddEdge(a, b);
|
sel->AddEdge(a, b);
|
||||||
if(leaky) *leaky = true;
|
if(leaky) *leaky = true;
|
||||||
|
@ -706,3 +714,35 @@ void SKdNode::MakeNakedEdgesInto(SEdgeList *sel, bool *inter, bool *leaky) {
|
||||||
m.Clear();
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -222,8 +222,10 @@ public:
|
||||||
void MakeMeshInto(SMesh *m);
|
void MakeMeshInto(SMesh *m);
|
||||||
void ClearTags(void);
|
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 MakeNakedEdgesInto(SEdgeList *sel, bool *inter=NULL, bool *leaky=NULL);
|
||||||
|
void MakeTurningEdgesInto(SEdgeList *sel);
|
||||||
|
|
||||||
void OcclusionTestLine(SEdge orig, SEdgeList *sel, int cnt);
|
void OcclusionTestLine(SEdge orig, SEdgeList *sel, int cnt);
|
||||||
void SplitLinesAgainstTriangle(SEdgeList *sel, STriangle *tr);
|
void SplitLinesAgainstTriangle(SEdgeList *sel, STriangle *tr);
|
||||||
|
|
|
@ -54,6 +54,10 @@ void SolveSpace::Init(char *cmdLine) {
|
||||||
exportOffset = CnfThawFloat(0.0f, "ExportOffset");
|
exportOffset = CnfThawFloat(0.0f, "ExportOffset");
|
||||||
// Draw back faces of triangles (when mesh is leaky/self-intersecting)
|
// Draw back faces of triangles (when mesh is leaky/self-intersecting)
|
||||||
drawBackFaces = CnfThawDWORD(1, "DrawBackFaces");
|
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
|
// Show toolbar in the graphics window
|
||||||
showToolbar = CnfThawDWORD(1, "ShowToolbar");
|
showToolbar = CnfThawDWORD(1, "ShowToolbar");
|
||||||
// Recent files menus
|
// Recent files menus
|
||||||
|
@ -118,6 +122,10 @@ void SolveSpace::Exit(void) {
|
||||||
CnfFreezeFloat(exportOffset, "ExportOffset");
|
CnfFreezeFloat(exportOffset, "ExportOffset");
|
||||||
// Draw back faces of triangles (when mesh is leaky/self-intersecting)
|
// Draw back faces of triangles (when mesh is leaky/self-intersecting)
|
||||||
CnfFreezeDWORD(drawBackFaces, "DrawBackFaces");
|
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
|
// Show toolbar in the graphics window
|
||||||
CnfFreezeDWORD(showToolbar, "ShowToolbar");
|
CnfFreezeDWORD(showToolbar, "ShowToolbar");
|
||||||
|
|
||||||
|
|
|
@ -444,6 +444,8 @@ public:
|
||||||
float exportOffset;
|
float exportOffset;
|
||||||
int drawBackFaces;
|
int drawBackFaces;
|
||||||
int showToolbar;
|
int showToolbar;
|
||||||
|
int exportShadedTriangles;
|
||||||
|
int exportExactCurves;
|
||||||
|
|
||||||
int CircleSides(double r);
|
int CircleSides(double r);
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
@ -36,12 +36,14 @@ hs(SS.GW.showConstraints), (DWORD)(&SS.GW.showConstraints), &(SS.GW.ToggleBool)
|
||||||
);
|
);
|
||||||
Printf(false, "%Bt%Ft "
|
Printf(false, "%Bt%Ft "
|
||||||
"%Fp%Ll%D%fshaded%E "
|
"%Fp%Ll%D%fshaded%E "
|
||||||
"%Fp%Ll%D%ffaces%E "
|
"%Fp%Ll%D%fedges%E "
|
||||||
"%Fp%Ll%D%fmesh%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.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.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)
|
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;
|
SS.drawBackFaces = !SS.drawBackFaces;
|
||||||
InvalidateGraphics();
|
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) {
|
void TextWindow::ShowConfiguration(void) {
|
||||||
int i;
|
int i;
|
||||||
Printf(true, "%Ft material color-(r, g, b)");
|
Printf(true, "%Ft material color-(r, g, b)");
|
||||||
|
@ -633,7 +643,7 @@ void TextWindow::ShowConfiguration(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Printf(false, "");
|
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",
|
Printf(false, "%Ba %@, %@, %@ %Fl%Ll%f%D[change]%E",
|
||||||
REDf(SS.edgeColor), GREENf(SS.edgeColor), BLUEf(SS.edgeColor),
|
REDf(SS.edgeColor), GREENf(SS.edgeColor), BLUEf(SS.edgeColor),
|
||||||
&ScreenChangeEdgeColor, 0);
|
&ScreenChangeEdgeColor, 0);
|
||||||
|
@ -665,6 +675,24 @@ void TextWindow::ShowConfiguration(void) {
|
||||||
(double)SS.exportOffset,
|
(double)SS.exportOffset,
|
||||||
&ScreenChangeExportOffset, 0);
|
&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, "");
|
||||||
Printf(false, "%Ft draw back faces: "
|
Printf(false, "%Ft draw back faces: "
|
||||||
"%Fh%f%Ll%s%E%Fs%s%E / %Fh%f%Ll%s%E%Fs%s%E",
|
"%Fh%f%Ll%s%E%Fs%s%E / %Fh%f%Ll%s%E%Fs%s%E",
|
||||||
|
|
3
ui.h
3
ui.h
|
@ -145,6 +145,8 @@ public:
|
||||||
static void ScreenGoToWebsite(int link, DWORD v);
|
static void ScreenGoToWebsite(int link, DWORD v);
|
||||||
|
|
||||||
static void ScreenChangeBackFaces(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 ScreenStepDimSteps(int link, DWORD v);
|
||||||
static void ScreenStepDimFinish(int link, DWORD v);
|
static void ScreenStepDimFinish(int link, DWORD v);
|
||||||
|
@ -405,6 +407,7 @@ public:
|
||||||
bool showConstraints;
|
bool showConstraints;
|
||||||
bool showTextWindow;
|
bool showTextWindow;
|
||||||
bool showShaded;
|
bool showShaded;
|
||||||
|
bool showEdges;
|
||||||
bool showFaces;
|
bool showFaces;
|
||||||
bool showMesh;
|
bool showMesh;
|
||||||
bool showHdnLines;
|
bool showHdnLines;
|
||||||
|
|
|
@ -2,15 +2,14 @@
|
||||||
marching algorithm for surface intersection
|
marching algorithm for surface intersection
|
||||||
surfaces of revolution (lathed)
|
surfaces of revolution (lathed)
|
||||||
cylinder-line special cases
|
cylinder-line special cases
|
||||||
exact boundaries when near pwl trim
|
boundary avoidance when casting ray for point-in-shell
|
||||||
tangent intersections
|
tangent intersections
|
||||||
short pwl edge avoidance
|
short pwl edge avoidance
|
||||||
exact curve export (at least for dxf)
|
exact curve export (at least for dxf)
|
||||||
hidden line removal from mesh
|
|
||||||
line styles (color, thickness)
|
|
||||||
assembly
|
assembly
|
||||||
|
|
||||||
-----
|
-----
|
||||||
|
line styles (color, thickness)
|
||||||
loop detection
|
loop detection
|
||||||
incremental regen of entities?
|
incremental regen of entities?
|
||||||
IGES and STEP export
|
IGES and STEP export
|
||||||
|
|
Loading…
Reference in New Issue
Block a user