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.
This commit is contained in:
Evil-Spirit 2016-11-14 22:16:50 +07:00 committed by whitequark
parent 3b241392d4
commit fdd08cbead
3 changed files with 37 additions and 29 deletions

View File

@ -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")) {

View File

@ -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:

View File

@ -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,