summaryrefslogtreecommitdiff
path: root/assetFactory
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2023-03-20 18:55:44 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2023-03-20 18:55:44 +0000
commitfe1913b3f3742077763d7a6fc9fcac219900a4ae (patch)
tree3f5ae92090aa816f570ebb8b93e58082b0051ca6 /assetFactory
parentSupport applying a single face controller to multiple faces (diff)
downloadilt-fe1913b3f3742077763d7a6fc9fcac219900a4ae.tar.bz2
ilt-fe1913b3f3742077763d7a6fc9fcac219900a4ae.tar.xz
ilt-fe1913b3f3742077763d7a6fc9fcac219900a4ae.zip
Slightly tidier FaceController? It's still a mess
Diffstat (limited to 'assetFactory')
-rw-r--r--assetFactory/faceController.cpp126
-rw-r--r--assetFactory/faceController.h3
2 files changed, 68 insertions, 61 deletions
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<const OpenMesh::FaceHandle> 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<glm::vec3> {},
- [&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, &centre](auto && p) {
- p = centre + ((p - centre) % mutation);
- });
- // create new vertices
- std::vector<OpenMesh::VertexHandle> 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<glm::vec3> {}, [&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(), &centre](auto && p) {
+ p = centre + ((p - centre) % mutation);
+ });
+ // create new vertices
+ std::vector<OpenMesh::VertexHandle> 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
diff --git a/assetFactory/faceController.h b/assetFactory/faceController.h
index 890aafa..962a516 100644
--- a/assetFactory/faceController.h
+++ b/assetFactory/faceController.h
@@ -31,4 +31,7 @@ private:
void applySingle(ModelFactoryMesh & mesh, const Style::StyleStack & parents, const std::string & name,
Shape::CreatedFaces & faces) const;
+ static std::string getAdjacentFaceName(const ModelFactoryMesh & mesh,
+ const std::span<const OpenMesh::FaceHandle> ofrange, OpenMesh::FaceHandle nf);
+ Shape::CreatedFaces extrude(ModelFactoryMesh & mesh, const std::string & faceName, OpenMesh::FaceHandle) const;
};