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:
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
Block a user