From d862385c8956b9cc1002323feddf0b65a777a1c1 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 19 Mar 2023 23:52:22 +0000 Subject: Use OpenMesh built-in to calculate face centre --- assetFactory/faceController.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'assetFactory/faceController.cpp') diff --git a/assetFactory/faceController.cpp b/assetFactory/faceController.cpp index 1ec1467..2fb0412 100644 --- a/assetFactory/faceController.cpp +++ b/assetFactory/faceController.cpp @@ -33,8 +33,7 @@ FaceController::apply(ModelFactoryMesh & mesh, const StyleStack & parents, const return std::move(out); }); const auto vertexCount = points.size(); - const auto centre - = std::accumulate(points.begin(), points.end(), glm::vec3 {}) / static_cast(vertexCount); + const auto centre = mesh.calc_face_centroid(cf.second); if (type == "extrude") { Shape::CreatedFaces newFaces; // mutate points -- cgit v1.2.3 From 5f0fbcef6dbc1421ea2b538c7f839b2f37c6e36e Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 20 Mar 2023 00:11:43 +0000 Subject: Fix some name shadowing in FaceController --- assetFactory/faceController.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'assetFactory/faceController.cpp') diff --git a/assetFactory/faceController.cpp b/assetFactory/faceController.cpp index 2fb0412..1e563b2 100644 --- a/assetFactory/faceController.cpp +++ b/assetFactory/faceController.cpp @@ -52,9 +52,9 @@ FaceController::apply(ModelFactoryMesh & mesh, const StyleStack & parents, const const auto next = (idx + 1) % vertexCount; const auto newFace = mesh.add_face({baseVertices[idx], baseVertices[next], vertices[next], vertices[idx]}); - auto & name = mesh.property(mesh.nameFaceProperty, newFace); - name = getAdjacentFaceName(ofrange, newFace); - newFaces.emplace(name, newFace); + auto & newFaceName = mesh.property(mesh.nameFaceProperty, newFace); + newFaceName = getAdjacentFaceName(ofrange, newFace); + newFaces.emplace(newFaceName, newFace); } newFaces.emplace(name, mesh.add_face(vertices)); if (smooth) { @@ -63,8 +63,8 @@ FaceController::apply(ModelFactoryMesh & mesh, const StyleStack & parents, const } } applyStyle(mesh, parents + this, newFaces); - for (const auto & [name, faceController] : faceControllers) { - faceController->apply(mesh, parents + this, name, newFaces); + for (const auto & [subFaceName, faceController] : faceControllers) { + faceController->apply(mesh, parents + this, subFaceName, newFaces); } faces.merge(std::move(newFaces)); } -- cgit v1.2.3 From b5db39e7de50cff669920ab1f279df223d257a51 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 20 Mar 2023 00:26:16 +0000 Subject: Support applying a single face controller to multiple faces --- assetFactory/faceController.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'assetFactory/faceController.cpp') diff --git a/assetFactory/faceController.cpp b/assetFactory/faceController.cpp index 1e563b2..6493300 100644 --- a/assetFactory/faceController.cpp +++ b/assetFactory/faceController.cpp @@ -4,7 +4,18 @@ #include "modelFactoryMesh.h" void -FaceController::apply(ModelFactoryMesh & mesh, const StyleStack & parents, const std::string & name, +FaceController::apply(ModelFactoryMesh & mesh, const StyleStack & parents, const std::string & names, + Shape::CreatedFaces & faces) const +{ + std::stringstream nameStream {names}; + std::for_each(std::istream_iterator(nameStream), std::istream_iterator {}, + [&](const auto & name) { + applySingle(mesh, parents, name, faces); + }); +} + +void +FaceController::applySingle(ModelFactoryMesh & mesh, const StyleStack & parents, const std::string & name, Shape::CreatedFaces & faces) const { const auto getAdjacentFaceName = [&mesh](const auto & ofrange, OpenMesh::FaceHandle nf) -> std::string { -- cgit v1.2.3 From fe1913b3f3742077763d7a6fc9fcac219900a4ae Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 20 Mar 2023 18:55:44 +0000 Subject: Slightly tidier FaceController? It's still a mess --- assetFactory/faceController.cpp | 126 +++++++++++++++++++++------------------- 1 file changed, 65 insertions(+), 61 deletions(-) (limited to 'assetFactory/faceController.cpp') diff --git a/assetFactory/faceController.cpp b/assetFactory/faceController.cpp index 6493300..bafbee2 100644 --- a/assetFactory/faceController.cpp +++ b/assetFactory/faceController.cpp @@ -14,82 +14,86 @@ FaceController::apply(ModelFactoryMesh & mesh, const StyleStack & parents, const }); } +std::string +FaceController::getAdjacentFaceName( + const ModelFactoryMesh & mesh, const std::span ofrange, OpenMesh::FaceHandle nf) +{ + const auto nfrange = mesh.ff_range(nf); + if (const auto target = std::find_first_of(ofrange.begin(), ofrange.end(), nfrange.begin(), nfrange.end()); + target != ofrange.end()) { + return mesh.property(mesh.nameFaceProperty, *target); + }; + return {}; +}; + void FaceController::applySingle(ModelFactoryMesh & mesh, const StyleStack & parents, const std::string & name, Shape::CreatedFaces & faces) const { - const auto getAdjacentFaceName = [&mesh](const auto & ofrange, OpenMesh::FaceHandle nf) -> std::string { - const auto nfrange = mesh.ff_range(nf); - if (const auto target = std::find_first_of(ofrange.begin(), ofrange.end(), nfrange.begin(), nfrange.end()); - target != ofrange.end()) { - return mesh.property(mesh.nameFaceProperty, *target); - }; - return {}; - }; - const auto controlledFaces {materializeRange(faces.equal_range(name))}; if (controlledFaces.empty()) { throw std::runtime_error("Named face(s) do not exist: " + name); } if (!type.empty()) { - const auto mutation = getMatrix(); faces.erase(name); - for (const auto & cf : controlledFaces) { - // get points - const auto baseVertices {materializeRange(mesh.fv_range(cf.second))}; - auto points = std::accumulate(baseVertices.begin(), baseVertices.end(), std::vector {}, - [&mesh](auto && out, auto && v) { - out.push_back(mesh.point(v)); - return std::move(out); - }); - const auto vertexCount = points.size(); - const auto centre = mesh.calc_face_centroid(cf.second); - if (type == "extrude") { - Shape::CreatedFaces newFaces; - // mutate points - std::for_each(points.begin(), points.end(), [&mutation, ¢re](auto && p) { - p = centre + ((p - centre) % mutation); - }); - // create new vertices - std::vector vertices; - std::transform(points.begin(), points.end(), std::back_inserter(vertices), [&mesh](auto && p) { - return mesh.add_vertex(p); - }); - // create new faces - const auto ofrange = materializeRange(mesh.ff_range(cf.second)); - mesh.delete_face(cf.second); - for (size_t idx {}; idx < vertexCount; ++idx) { - const auto next = (idx + 1) % vertexCount; - const auto newFace - = mesh.add_face({baseVertices[idx], baseVertices[next], vertices[next], vertices[idx]}); - auto & newFaceName = mesh.property(mesh.nameFaceProperty, newFace); - newFaceName = getAdjacentFaceName(ofrange, newFace); - newFaces.emplace(newFaceName, newFace); - } - newFaces.emplace(name, mesh.add_face(vertices)); - if (smooth) { - for (const auto & [name, face] : newFaces) { - mesh.property(mesh.smoothFaceProperty, face) = true; - } - } - applyStyle(mesh, parents + this, newFaces); - for (const auto & [subFaceName, faceController] : faceControllers) { - faceController->apply(mesh, parents + this, subFaceName, newFaces); - } - faces.merge(std::move(newFaces)); - } - else { - mesh.property(mesh.smoothFaceProperty, cf.second) = smooth; - applyStyle(mesh, parents + this, cf.second); + } + for (const auto & [faceName, faceHandle] : controlledFaces) { + if (type == "extrude") { + auto newFaces = extrude(mesh, faceName, faceHandle); + applyStyle(mesh, parents + this, newFaces); + for (const auto & [subFaceName, faceController] : faceControllers) { + faceController->apply(mesh, parents + this, subFaceName, newFaces); } + faces.merge(std::move(newFaces)); } - } - else { - for (const auto & cf : controlledFaces) { - applyStyle(mesh, parents + this, cf.second); + else { + mesh.property(mesh.smoothFaceProperty, faceHandle) = smooth; + applyStyle(mesh, parents + this, faceHandle); } } + for (const auto & [faceName, faceHandle] : controlledFaces) { + mesh.property(mesh.smoothFaceProperty, faceHandle) = smooth; + applyStyle(mesh, parents + this, faceHandle); + } +} + +Shape::CreatedFaces +FaceController::extrude(ModelFactoryMesh & mesh, const std::string & faceName, OpenMesh::FaceHandle faceHandle) const +{ + // get points + const auto baseVertices {materializeRange(mesh.fv_range(faceHandle))}; + auto points = std::accumulate( + baseVertices.begin(), baseVertices.end(), std::vector {}, [&mesh](auto && out, auto && v) { + out.push_back(mesh.point(v)); + return std::move(out); + }); + const auto vertexCount = points.size(); + const auto centre = mesh.calc_face_centroid(faceHandle); + Shape::CreatedFaces newFaces; + // mutate points + std::for_each(points.begin(), points.end(), [mutation = getMatrix(), ¢re](auto && p) { + p = centre + ((p - centre) % mutation); + }); + // create new vertices + std::vector vertices; + std::transform(points.begin(), points.end(), std::back_inserter(vertices), [&mesh](auto && p) { + return mesh.add_vertex(p); + }); + // create new faces + const auto ofrange = materializeRange(mesh.ff_range(faceHandle)); + mesh.delete_face(faceHandle); + for (size_t idx {}; idx < vertexCount; ++idx) { + const auto next = (idx + 1) % vertexCount; + const auto newFace = mesh.add_face({baseVertices[idx], baseVertices[next], vertices[next], vertices[idx]}); + auto & newFaceName = mesh.property(mesh.nameFaceProperty, newFace); + newFaceName = getAdjacentFaceName(mesh, ofrange, newFace); + newFaces.emplace(newFaceName, newFace); + mesh.property(mesh.smoothFaceProperty, newFace) = smooth; + } + mesh.property(mesh.smoothFaceProperty, newFaces.emplace(faceName, mesh.add_face(vertices))->second) = smooth; + + return newFaces; } bool -- cgit v1.2.3 From 2508112e2853e1a6c012b19c7232aa09f98d3969 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 20 Mar 2023 23:30:21 +0000 Subject: Move smooth property into Style and make it optional This allows it to cascade down as faces are created and also be overridden as required --- assetFactory/faceController.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'assetFactory/faceController.cpp') diff --git a/assetFactory/faceController.cpp b/assetFactory/faceController.cpp index bafbee2..2367f8d 100644 --- a/assetFactory/faceController.cpp +++ b/assetFactory/faceController.cpp @@ -48,12 +48,10 @@ FaceController::applySingle(ModelFactoryMesh & mesh, const StyleStack & parents, faces.merge(std::move(newFaces)); } else { - mesh.property(mesh.smoothFaceProperty, faceHandle) = smooth; applyStyle(mesh, parents + this, faceHandle); } } for (const auto & [faceName, faceHandle] : controlledFaces) { - mesh.property(mesh.smoothFaceProperty, faceHandle) = smooth; applyStyle(mesh, parents + this, faceHandle); } } @@ -89,9 +87,8 @@ FaceController::extrude(ModelFactoryMesh & mesh, const std::string & faceName, O auto & newFaceName = mesh.property(mesh.nameFaceProperty, newFace); newFaceName = getAdjacentFaceName(mesh, ofrange, newFace); newFaces.emplace(newFaceName, newFace); - mesh.property(mesh.smoothFaceProperty, newFace) = smooth; } - mesh.property(mesh.smoothFaceProperty, newFaces.emplace(faceName, mesh.add_face(vertices))->second) = smooth; + newFaces.emplace(faceName, mesh.add_face(vertices)); return newFaces; } @@ -99,7 +96,6 @@ FaceController::extrude(ModelFactoryMesh & mesh, const std::string & faceName, O bool FaceController::persist(Persistence::PersistenceStore & store) { - return STORE_TYPE && STORE_MEMBER(id) && Style::persist(store) && STORE_MEMBER(type) && STORE_MEMBER(smooth) - && Mutation::persist(store) + return STORE_TYPE && STORE_MEMBER(id) && Style::persist(store) && STORE_MEMBER(type) && Mutation::persist(store) && STORE_NAME_HELPER("face", faceControllers, Persistence::MapByMember); } -- cgit v1.2.3 From 37e39b6c00834f4711576c7f77cb0b7b5d558956 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 21 Mar 2023 00:18:25 +0000 Subject: Apply styles in first loop over controlled faces --- assetFactory/faceController.cpp | 5 ----- 1 file changed, 5 deletions(-) (limited to 'assetFactory/faceController.cpp') diff --git a/assetFactory/faceController.cpp b/assetFactory/faceController.cpp index 2367f8d..25bf833 100644 --- a/assetFactory/faceController.cpp +++ b/assetFactory/faceController.cpp @@ -47,11 +47,6 @@ FaceController::applySingle(ModelFactoryMesh & mesh, const StyleStack & parents, } faces.merge(std::move(newFaces)); } - else { - applyStyle(mesh, parents + this, faceHandle); - } - } - for (const auto & [faceName, faceHandle] : controlledFaces) { applyStyle(mesh, parents + this, faceHandle); } } -- cgit v1.2.3 From 2bcbb86db4061e32005adea8806e4ac552691bcf Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Fri, 7 Apr 2023 23:55:09 +0100 Subject: Extend face controller to support splitting a face along a plane Individual parts of the splits faces can then be styled separately --- assetFactory/faceController.cpp | 83 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 75 insertions(+), 8 deletions(-) (limited to 'assetFactory/faceController.cpp') diff --git a/assetFactory/faceController.cpp b/assetFactory/faceController.cpp index 25bf833..28812d8 100644 --- a/assetFactory/faceController.cpp +++ b/assetFactory/faceController.cpp @@ -2,6 +2,7 @@ #include "collections.hpp" #include "maths.h" #include "modelFactoryMesh.h" +#include void FaceController::apply(ModelFactoryMesh & mesh, const StyleStack & parents, const std::string & names, @@ -30,24 +31,29 @@ void FaceController::applySingle(ModelFactoryMesh & mesh, const StyleStack & parents, const std::string & name, Shape::CreatedFaces & faces) const { - const auto controlledFaces {materializeRange(faces.equal_range(name))}; - if (controlledFaces.empty()) { - throw std::runtime_error("Named face(s) do not exist: " + name); - } + auto controlledFaces {materializeRange(faces.equal_range(name))}; - if (!type.empty()) { + if (!type.empty() || !splits.empty()) { faces.erase(name); } - for (const auto & [faceName, faceHandle] : controlledFaces) { + for (auto & [faceName, faceHandle] : controlledFaces) { + Shape::CreatedFaces newFaces; + for (const auto & [newFaceSuffix, splitDef] : splits) { + newFaces.merge(split(mesh, name + newFaceSuffix, faceHandle, *splitDef)); + } if (type == "extrude") { - auto newFaces = extrude(mesh, faceName, faceHandle); + newFaces.merge(extrude(mesh, name, faceHandle)); + } + if (!newFaces.empty()) { applyStyle(mesh, parents + this, newFaces); for (const auto & [subFaceName, faceController] : faceControllers) { faceController->apply(mesh, parents + this, subFaceName, newFaces); } faces.merge(std::move(newFaces)); } - applyStyle(mesh, parents + this, faceHandle); + else { + applyStyle(mesh, parents + this, faceHandle); + } } } @@ -88,9 +94,70 @@ FaceController::extrude(ModelFactoryMesh & mesh, const std::string & faceName, O return newFaces; } +enum class PlaneRelation { Above, Below, On }; +Shape::CreatedFaces +FaceController::split( + ModelFactoryMesh & mesh, const std::string & name, OpenMesh::FaceHandle & fh, const Split & split) const +{ + // Map face vertex handles to their relationship to the split plane + const auto vertices = materializeRange(mesh.fv_range(fh)); + auto vertexRelations = vertices * [&split, &mesh](OpenMesh::VertexHandle vh) { + const auto d = glm::dot(split.normal, mesh.point(vh) - split.origin); + return std::make_pair(vh, d < 0.f ? PlaneRelation::Below : d > 0.f ? PlaneRelation::Above : PlaneRelation::On); + }; + // Insert new vertices where half edges intersect the split plane + for (size_t curIdx = 0; curIdx < vertexRelations.size(); ++curIdx) { + const size_t nextIdx = (curIdx + 1) % vertexRelations.size(); + const auto ¤t = vertexRelations[curIdx], next = vertexRelations[nextIdx]; + if ((current.second == PlaneRelation::Above && next.second == PlaneRelation::Below) + || (current.second == PlaneRelation::Below && next.second == PlaneRelation::Above)) { + const auto origin = mesh.point(current.first), dir = glm::normalize(mesh.point(next.first) - origin); + + float dist {}; + glm::intersectRayPlane(origin, dir, split.origin, split.normal, dist); + const auto newv = mesh.add_vertex(origin + (dir * dist)); + auto where = vertexRelations.begin(); + ++curIdx; + std::advance(where, curIdx); + vertexRelations.emplace(where, newv, PlaneRelation::On); + } + } + // Create vertex vectors + std::array, 2> out; + auto filterVertices = [&vertexRelations](auto & out, auto notRelation) { + for (const auto & vhr : vertexRelations) { + if (vhr.second != notRelation) { + out.emplace_back(vhr.first); + } + } + }; + filterVertices(out.front(), PlaneRelation::Above); + filterVertices(out.back(), PlaneRelation::Below); + + if (out.back().size() > 2) { + Shape::CreatedFaces newFaces; + const auto oldName = mesh.property(mesh.nameFaceProperty, fh); + mesh.delete_face(fh); + const auto newf1 = newFaces.insert(mesh.add_namedFace(oldName, out.front()))->second; + const auto newf2 = newFaces.insert(mesh.add_namedFace(name, out.back()))->second; + mesh.copy_property(mesh.smoothFaceProperty, fh, newf1); + mesh.copy_property(mesh.smoothFaceProperty, fh, newf2); + fh = newf1; + return newFaces; + } + return {}; +} + bool FaceController::persist(Persistence::PersistenceStore & store) { return STORE_TYPE && STORE_MEMBER(id) && Style::persist(store) && STORE_MEMBER(type) && Mutation::persist(store) + && STORE_NAME_HELPER("split", splits, Persistence::MapByMember) && STORE_NAME_HELPER("face", faceControllers, Persistence::MapByMember); } + +bool +FaceController::Split::persist(Persistence::PersistenceStore & store) +{ + return STORE_TYPE && STORE_MEMBER(id) && STORE_MEMBER(origin) && STORE_MEMBER(normal); +} -- cgit v1.2.3 From 5ffac39b0edfe04c081191b399cadcd69ad3ccd2 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 8 Apr 2023 11:46:51 +0100 Subject: Generate extrusion face names from halfedge adjacent face names --- assetFactory/faceController.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'assetFactory/faceController.cpp') diff --git a/assetFactory/faceController.cpp b/assetFactory/faceController.cpp index 28812d8..92cc8d2 100644 --- a/assetFactory/faceController.cpp +++ b/assetFactory/faceController.cpp @@ -69,7 +69,6 @@ FaceController::extrude(ModelFactoryMesh & mesh, const std::string & faceName, O }); const auto vertexCount = points.size(); const auto centre = mesh.calc_face_centroid(faceHandle); - Shape::CreatedFaces newFaces; // mutate points std::for_each(points.begin(), points.end(), [mutation = getMatrix(), ¢re](auto && p) { p = centre + ((p - centre) % mutation); @@ -79,17 +78,22 @@ FaceController::extrude(ModelFactoryMesh & mesh, const std::string & faceName, O std::transform(points.begin(), points.end(), std::back_inserter(vertices), [&mesh](auto && p) { return mesh.add_vertex(p); }); + // get new faces names + std::vector faceNames; + for (size_t idx {}; idx < vertexCount; ++idx) { + const auto next = (idx + 1) % vertexCount; + const auto existingEdge = mesh.find_halfedge(baseVertices[idx], baseVertices[next]); + faceNames.push_back(mesh.property(mesh.nameAdjFaceProperty, existingEdge)); + } // create new faces - const auto ofrange = materializeRange(mesh.ff_range(faceHandle)); mesh.delete_face(faceHandle); + Shape::CreatedFaces newFaces; for (size_t idx {}; idx < vertexCount; ++idx) { const auto next = (idx + 1) % vertexCount; - const auto newFace = mesh.add_face({baseVertices[idx], baseVertices[next], vertices[next], vertices[idx]}); - auto & newFaceName = mesh.property(mesh.nameFaceProperty, newFace); - newFaceName = getAdjacentFaceName(mesh, ofrange, newFace); - newFaces.emplace(newFaceName, newFace); + newFaces.emplace(mesh.add_namedFace( + faceNames[idx], baseVertices[idx], baseVertices[next], vertices[next], vertices[idx])); } - newFaces.emplace(faceName, mesh.add_face(vertices)); + newFaces.emplace(mesh.add_namedFace(faceName, vertices)); return newFaces; } -- cgit v1.2.3 From 144f9b57295f7fee9306ee1a4480c165a834e6ca Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 8 Apr 2023 11:48:17 +0100 Subject: Remove no longer required getAdjacentFaceName --- assetFactory/faceController.cpp | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'assetFactory/faceController.cpp') diff --git a/assetFactory/faceController.cpp b/assetFactory/faceController.cpp index 92cc8d2..7e4b0e1 100644 --- a/assetFactory/faceController.cpp +++ b/assetFactory/faceController.cpp @@ -15,18 +15,6 @@ FaceController::apply(ModelFactoryMesh & mesh, const StyleStack & parents, const }); } -std::string -FaceController::getAdjacentFaceName( - const ModelFactoryMesh & mesh, const std::span ofrange, OpenMesh::FaceHandle nf) -{ - const auto nfrange = mesh.ff_range(nf); - if (const auto target = std::find_first_of(ofrange.begin(), ofrange.end(), nfrange.begin(), nfrange.end()); - target != ofrange.end()) { - return mesh.property(mesh.nameFaceProperty, *target); - }; - return {}; -}; - void FaceController::applySingle(ModelFactoryMesh & mesh, const StyleStack & parents, const std::string & name, Shape::CreatedFaces & faces) const -- cgit v1.2.3 From fe5a06851823ac6da841a513cf59140c63ff69f3 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 8 Apr 2023 14:08:25 +0100 Subject: Simplify extruding --- assetFactory/faceController.cpp | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) (limited to 'assetFactory/faceController.cpp') diff --git a/assetFactory/faceController.cpp b/assetFactory/faceController.cpp index 7e4b0e1..7992fba 100644 --- a/assetFactory/faceController.cpp +++ b/assetFactory/faceController.cpp @@ -50,23 +50,13 @@ FaceController::extrude(ModelFactoryMesh & mesh, const std::string & faceName, O { // get points const auto baseVertices {materializeRange(mesh.fv_range(faceHandle))}; - auto points = std::accumulate( - baseVertices.begin(), baseVertices.end(), std::vector {}, [&mesh](auto && out, auto && v) { - out.push_back(mesh.point(v)); - return std::move(out); - }); - const auto vertexCount = points.size(); - const auto centre = mesh.calc_face_centroid(faceHandle); - // mutate points - std::for_each(points.begin(), points.end(), [mutation = getMatrix(), ¢re](auto && p) { - p = centre + ((p - centre) % mutation); - }); // create new vertices - std::vector vertices; - std::transform(points.begin(), points.end(), std::back_inserter(vertices), [&mesh](auto && p) { - return mesh.add_vertex(p); - }); + const auto vertices + = baseVertices * [&mesh, mutation = getMatrix(), centre = mesh.calc_face_centroid(faceHandle)](auto && v) { + return mesh.add_vertex(centre + ((mesh.point(v) - centre) % mutation)); + }; // get new faces names + const auto vertexCount = baseVertices.size(); std::vector faceNames; for (size_t idx {}; idx < vertexCount; ++idx) { const auto next = (idx + 1) % vertexCount; -- cgit v1.2.3 From b222c21715384efc2eaa53d3ba295fb34da5b599 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 9 Apr 2023 12:24:55 +0100 Subject: Start to factor out geometric place from face controller split --- assetFactory/faceController.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'assetFactory/faceController.cpp') diff --git a/assetFactory/faceController.cpp b/assetFactory/faceController.cpp index 7992fba..37aaa4c 100644 --- a/assetFactory/faceController.cpp +++ b/assetFactory/faceController.cpp @@ -76,7 +76,6 @@ FaceController::extrude(ModelFactoryMesh & mesh, const std::string & faceName, O return newFaces; } -enum class PlaneRelation { Above, Below, On }; Shape::CreatedFaces FaceController::split( ModelFactoryMesh & mesh, const std::string & name, OpenMesh::FaceHandle & fh, const Split & split) const @@ -84,15 +83,16 @@ FaceController::split( // Map face vertex handles to their relationship to the split plane const auto vertices = materializeRange(mesh.fv_range(fh)); auto vertexRelations = vertices * [&split, &mesh](OpenMesh::VertexHandle vh) { - const auto d = glm::dot(split.normal, mesh.point(vh) - split.origin); - return std::make_pair(vh, d < 0.f ? PlaneRelation::Below : d > 0.f ? PlaneRelation::Above : PlaneRelation::On); + return std::make_pair(vh, split.getRelation(mesh.point(vh))); }; // Insert new vertices where half edges intersect the split plane for (size_t curIdx = 0; curIdx < vertexRelations.size(); ++curIdx) { const size_t nextIdx = (curIdx + 1) % vertexRelations.size(); const auto ¤t = vertexRelations[curIdx], next = vertexRelations[nextIdx]; - if ((current.second == PlaneRelation::Above && next.second == PlaneRelation::Below) - || (current.second == PlaneRelation::Below && next.second == PlaneRelation::Above)) { + if ((current.second == GeometricPlane::PlaneRelation::Above + && next.second == GeometricPlane::PlaneRelation::Below) + || (current.second == GeometricPlane::PlaneRelation::Below + && next.second == GeometricPlane::PlaneRelation::Above)) { const auto origin = mesh.point(current.first), dir = glm::normalize(mesh.point(next.first) - origin); float dist {}; @@ -101,7 +101,7 @@ FaceController::split( auto where = vertexRelations.begin(); ++curIdx; std::advance(where, curIdx); - vertexRelations.emplace(where, newv, PlaneRelation::On); + vertexRelations.emplace(where, newv, GeometricPlane::PlaneRelation::On); } } // Create vertex vectors @@ -113,8 +113,8 @@ FaceController::split( } } }; - filterVertices(out.front(), PlaneRelation::Above); - filterVertices(out.back(), PlaneRelation::Below); + filterVertices(out.front(), GeometricPlane::PlaneRelation::Above); + filterVertices(out.back(), GeometricPlane::PlaneRelation::Below); if (out.back().size() > 2) { Shape::CreatedFaces newFaces; -- cgit v1.2.3 From a74ee2960bd8c930b91dbc897c27d134f5f2c2f0 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 9 Apr 2023 15:51:47 +0100 Subject: Move remaining split/plane functions to use library --- assetFactory/faceController.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'assetFactory/faceController.cpp') diff --git a/assetFactory/faceController.cpp b/assetFactory/faceController.cpp index 37aaa4c..b305f1c 100644 --- a/assetFactory/faceController.cpp +++ b/assetFactory/faceController.cpp @@ -2,7 +2,7 @@ #include "collections.hpp" #include "maths.h" #include "modelFactoryMesh.h" -#include +#include "ray.hpp" void FaceController::apply(ModelFactoryMesh & mesh, const StyleStack & parents, const std::string & names, @@ -89,15 +89,11 @@ FaceController::split( for (size_t curIdx = 0; curIdx < vertexRelations.size(); ++curIdx) { const size_t nextIdx = (curIdx + 1) % vertexRelations.size(); const auto ¤t = vertexRelations[curIdx], next = vertexRelations[nextIdx]; - if ((current.second == GeometricPlane::PlaneRelation::Above - && next.second == GeometricPlane::PlaneRelation::Below) - || (current.second == GeometricPlane::PlaneRelation::Below - && next.second == GeometricPlane::PlaneRelation::Above)) { - const auto origin = mesh.point(current.first), dir = glm::normalize(mesh.point(next.first) - origin); - - float dist {}; - glm::intersectRayPlane(origin, dir, split.origin, split.normal, dist); - const auto newv = mesh.add_vertex(origin + (dir * dist)); + if (GeometricPlane::isIntersect(current.second, next.second)) { + const auto ray = Ray::fromPoints(mesh.point(current.first), mesh.point(next.first)); + const auto intersect = split.getRayIntersectPosition(ray); + assert(intersect); + const auto newv = mesh.add_vertex(intersect->position); auto where = vertexRelations.begin(); ++curIdx; std::advance(where, curIdx); -- cgit v1.2.3