From 8fd11f48869a7d9d884da91055f14fd37d053fa1 Mon Sep 17 00:00:00 2001 From: EvilSpirit Date: Tue, 21 Mar 2017 22:47:59 +0700 Subject: [PATCH] Fix forcing NURBS to mesh in a step group when the flag is inherited. Before this commit, if the source group of a step rotate/translate group is forced to triangle mesh, the UI would show that the step rotate/translate group is also forced to triangle mesh, but the group would in fact contain NURBS surfaces. --- CHANGELOG.md | 2 ++ src/group.cpp | 17 +++++++++++++++++ src/groupmesh.cpp | 16 +++++++++++----- src/sketch.h | 6 ++++-- src/textscreens.cpp | 3 +-- 5 files changed, 35 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ebaf05d3..adab5ef1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -79,6 +79,8 @@ Bugs fixed: spurious changes in the sketch. * Points highlighted with "Analyze → Show Degrees of Freedom" are drawn on top of all other geometry. + * A step rotate/translate group using a group forced to triangle mesh + as a source group also gets forced to triangle mesh. 2.3 --- diff --git a/src/group.cpp b/src/group.cpp index 07d63a8b..20b4a765 100644 --- a/src/group.cpp +++ b/src/group.cpp @@ -318,6 +318,23 @@ void Group::TransformImportedBy(Vector t, Quaternion q) { SK.GetParam(qz)->val = qg.vz; } +bool Group::IsForcedToMeshBySource() const { + const Group *srcg = this; + if(type == Type::TRANSLATE || type == Type::ROTATE) { + // A step and repeat gets merged against the group's prevous group, + // not our own previous group. + srcg = SK.GetGroup(opA); + if(srcg->forceToMesh) return true; + } + Group *g = srcg->RunningMeshGroup(); + if(g == NULL) return false; + return g->forceToMesh || g->IsForcedToMeshBySource(); +} + +bool Group::IsForcedToMesh() const { + return forceToMesh || IsForcedToMeshBySource(); +} + std::string Group::DescriptionString() { if(name.empty()) { return ssprintf("g%03x-%s", h.v, _("(unnamed)")); diff --git a/src/groupmesh.cpp b/src/groupmesh.cpp index 92392140..f33dd0be 100644 --- a/src/groupmesh.cpp +++ b/src/groupmesh.cpp @@ -204,8 +204,14 @@ void Group::GenerateShellAndMesh() { srcg = SK.GetGroup(opA); if(!srcg->suppress) { - GenerateForStepAndRepeat(&(srcg->thisShell), &thisShell, srcg->meshCombine); - GenerateForStepAndRepeat (&(srcg->thisMesh), &thisMesh, srcg->meshCombine); + if(!IsForcedToMesh()) { + GenerateForStepAndRepeat(&(srcg->thisShell), &thisShell, srcg->meshCombine); + } else { + SMesh prevm = {}; + prevm.MakeFromCopyOf(&srcg->thisMesh); + srcg->thisShell.TriangulateInto(&prevm); + GenerateForStepAndRepeat (&prevm, &thisMesh, srcg->meshCombine); + } } } else if(type == Type::EXTRUDE && haveSrc) { Group *src = SK.GetGroup(opA); @@ -317,7 +323,7 @@ void Group::GenerateShellAndMesh() { Group *prevg = srcg->RunningMeshGroup(); - if(prevg->runningMesh.IsEmpty() && thisMesh.IsEmpty() && !forceToMesh) { + if(!IsForcedToMesh()) { SShell *prevs = &(prevg->runningShell); GenerateForBoolean(prevs, &thisShell, &runningShell, srcg->meshCombine); @@ -434,7 +440,7 @@ void Group::GenerateDisplayItems() { } } -Group *Group::PreviousGroup() { +Group *Group::PreviousGroup() const { int i; for(i = 0; i < SK.groupOrder.n; i++) { Group *g = SK.GetGroup(SK.groupOrder.elem[i]); @@ -444,7 +450,7 @@ Group *Group::PreviousGroup() { return SK.GetGroup(SK.groupOrder.elem[i - 1]); } -Group *Group::RunningMeshGroup() { +Group *Group::RunningMeshGroup() const { if(type == Type::TRANSLATE || type == Type::ROTATE) { return SK.GetGroup(opA)->RunningMeshGroup(); } else { diff --git a/src/sketch.h b/src/sketch.h index c7950c3a..c677dfe7 100644 --- a/src/sketch.h +++ b/src/sketch.h @@ -234,6 +234,8 @@ public: void Generate(EntityList *entity, ParamList *param); bool IsSolvedOkay(); void TransformImportedBy(Vector t, Quaternion q); + bool IsForcedToMeshBySource() const; + bool IsForcedToMesh() const; // When a request generates entities from entities, and the source // entities may have come from multiple requests, it's necessary to // remap the entity ID so that it's still unique. We do this with a @@ -271,8 +273,8 @@ public: void AssembleLoops(bool *allClosed, bool *allCoplanar, bool *allNonZeroLen); void GenerateLoops(); // And the mesh stuff - Group *PreviousGroup(); - Group *RunningMeshGroup(); + Group *PreviousGroup() const; + Group *RunningMeshGroup() const; bool IsMeshGroup(); void GenerateShellAndMesh(); diff --git a/src/textscreens.cpp b/src/textscreens.cpp index 2e1e519a..9998583f 100644 --- a/src/textscreens.cpp +++ b/src/textscreens.cpp @@ -395,8 +395,7 @@ void TextWindow::ShowGroupInfo() { &TextWindow::ScreenChangeGroupOption, g->visible ? CHECK_TRUE : CHECK_FALSE); - Group *pg; pg = g->PreviousGroup(); - if(pg && pg->runningMesh.IsEmpty() && g->thisMesh.IsEmpty()) { + if(!g->IsForcedToMeshBySource()) { Printf(false, " %f%Lf%Fd%s force NURBS surfaces to triangle mesh", &TextWindow::ScreenChangeGroupOption, g->forceToMesh ? CHECK_TRUE : CHECK_FALSE);