Warn if exporting a non-watertight mesh.
If a generated mesh is non-watertight, and this is not noticed for some reason (e.g. the markers are dismissed), and the mesh is exported for further processing, it could cause problems down the line.pull/109/head
parent
3b241392d4
commit
fdd08cbead
|
@ -812,7 +812,7 @@ void SolveSpaceUI::ExportMeshTo(const std::string &filename) {
|
|||
Error("Couldn't write to '%s'", filename.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
ShowNakedEdges(/*reportOnlyWhenNotOkay=*/true);
|
||||
if(FilenameHasExtension(filename, ".stl")) {
|
||||
ExportMeshAsStlTo(f, m);
|
||||
} else if(FilenameHasExtension(filename, ".obj")) {
|
||||
|
|
|
@ -596,34 +596,7 @@ void SolveSpaceUI::MenuAnalyze(Command id) {
|
|||
break;
|
||||
|
||||
case Command::NAKED_EDGES: {
|
||||
SS.nakedEdges.Clear();
|
||||
|
||||
Group *g = SK.GetGroup(SS.GW.activeGroup);
|
||||
SMesh *m = &(g->displayMesh);
|
||||
SKdNode *root = SKdNode::From(m);
|
||||
bool inters, leaks;
|
||||
root->MakeCertainEdgesInto(&(SS.nakedEdges),
|
||||
EdgeKind::NAKED_OR_SELF_INTER, /*coplanarIsInter=*/true, &inters, &leaks);
|
||||
|
||||
InvalidateGraphics();
|
||||
|
||||
const char *intersMsg = inters ?
|
||||
"The mesh is self-intersecting (NOT okay, invalid)." :
|
||||
"The mesh is not self-intersecting (okay, valid).";
|
||||
const char *leaksMsg = leaks ?
|
||||
"The mesh has naked edges (NOT okay, invalid)." :
|
||||
"The mesh is watertight (okay, valid).";
|
||||
|
||||
std::string cntMsg = ssprintf("\n\nThe model contains %d triangles, from "
|
||||
"%d surfaces.", g->displayMesh.l.n, g->runningShell.surface.n);
|
||||
|
||||
if(SS.nakedEdges.l.n == 0) {
|
||||
Message("%s\n\n%s\n\nZero problematic edges, good.%s",
|
||||
intersMsg, leaksMsg, cntMsg.c_str());
|
||||
} else {
|
||||
Error("%s\n\n%s\n\n%d problematic edges, bad.%s",
|
||||
intersMsg, leaksMsg, SS.nakedEdges.l.n, cntMsg.c_str());
|
||||
}
|
||||
ShowNakedEdges(/*reportOnlyWhenNotOkay=*/false);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -811,6 +784,40 @@ void SolveSpaceUI::MenuAnalyze(Command id) {
|
|||
}
|
||||
}
|
||||
|
||||
void SolveSpaceUI::ShowNakedEdges(bool reportOnlyWhenNotOkay) {
|
||||
SS.nakedEdges.Clear();
|
||||
|
||||
Group *g = SK.GetGroup(SS.GW.activeGroup);
|
||||
SMesh *m = &(g->displayMesh);
|
||||
SKdNode *root = SKdNode::From(m);
|
||||
bool inters, leaks;
|
||||
root->MakeCertainEdgesInto(&(SS.nakedEdges),
|
||||
EdgeKind::NAKED_OR_SELF_INTER, /*coplanarIsInter=*/true, &inters, &leaks);
|
||||
|
||||
if(reportOnlyWhenNotOkay && !inters && !leaks && SS.nakedEdges.l.n == 0) {
|
||||
return;
|
||||
}
|
||||
InvalidateGraphics();
|
||||
|
||||
const char *intersMsg = inters ?
|
||||
"The mesh is self-intersecting (NOT okay, invalid)." :
|
||||
"The mesh is not self-intersecting (okay, valid).";
|
||||
const char *leaksMsg = leaks ?
|
||||
"The mesh has naked edges (NOT okay, invalid)." :
|
||||
"The mesh is watertight (okay, valid).";
|
||||
|
||||
std::string cntMsg = ssprintf("\n\nThe model contains %d triangles, from "
|
||||
"%d surfaces.", g->displayMesh.l.n, g->runningShell.surface.n);
|
||||
|
||||
if(SS.nakedEdges.l.n == 0) {
|
||||
Message("%s\n\n%s\n\nZero problematic edges, good.%s",
|
||||
intersMsg, leaksMsg, cntMsg.c_str());
|
||||
} else {
|
||||
Error("%s\n\n%s\n\n%d problematic edges, bad.%s",
|
||||
intersMsg, leaksMsg, SS.nakedEdges.l.n, cntMsg.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void SolveSpaceUI::MenuHelp(Command id) {
|
||||
switch(id) {
|
||||
case Command::WEBSITE:
|
||||
|
|
|
@ -881,6 +881,7 @@ public:
|
|||
bool PruneGroups(hGroup hg);
|
||||
bool PruneRequests(hGroup hg);
|
||||
bool PruneConstraints(hGroup hg);
|
||||
static void ShowNakedEdges(bool reportOnlyWhenNotOkay);
|
||||
|
||||
enum class Generate : uint32_t {
|
||||
DIRTY,
|
||||
|
|
Loading…
Reference in New Issue