From c37f6cfdd2b67c59ef7e4bf4932d8a8c9ed8e978 Mon Sep 17 00:00:00 2001 From: Andy Baker Date: Sat, 11 May 2024 13:26:30 +0200 Subject: [PATCH] Add new order-2 operator "Valetta" --- .../Core/Runtime/PolyMesh.ConwayOps.cs | 90 +++++++++++++++++++ .../Core/Runtime/PolyMesh.cs | 6 +- 2 files changed, 95 insertions(+), 1 deletion(-) diff --git a/Packages/Polyhydra/com.ixxy.polyhydra/Core/Runtime/PolyMesh.ConwayOps.cs b/Packages/Polyhydra/com.ixxy.polyhydra/Core/Runtime/PolyMesh.ConwayOps.cs index babd04f..beea9be 100644 --- a/Packages/Polyhydra/com.ixxy.polyhydra/Core/Runtime/PolyMesh.ConwayOps.cs +++ b/Packages/Polyhydra/com.ixxy.polyhydra/Core/Runtime/PolyMesh.ConwayOps.cs @@ -2130,6 +2130,96 @@ public PolyMesh Stake(OpParams o, bool join = false) return new PolyMesh(vertexPoints, faceIndices, faceRoles, vertexRoles, newFaceTags); } + public PolyMesh Valletta(OpParams o) + { + var newFaceTags = new List>(); + + var faceIndices = new List(); + var vertexPoints = new List(); + var existingVertices = new Dictionary(); + var newInnerVertices = new Dictionary<(Guid, Guid)?, int>(); + + var faceRoles = new List(); + var vertexRoles = new List(); + + for (var i = 0; i < Vertices.Count; i++) + { + vertexPoints.Add(Vertices[i].Position); + vertexRoles.Add(Roles.Existing); + existingVertices[vertexPoints[i]] = i; + } + + int vertexIndex = vertexPoints.Count; + + for (var faceIndex = 0; faceIndex < Faces.Count; faceIndex++) + { + float ratio = o.GetValueA(this, faceIndex); + var prevFaceTagSet = FaceTags[faceIndex]; + var face = Faces[faceIndex]; + var edge = face.Halfedge; + var centroid = face.Centroid; + + // Generate the quads and triangles on this face + for (int i = 0; i < face.Sides; i++) + { + var newVertex = Vector3.LerpUnclamped( + edge.Midpoint, + centroid, + ratio + ); + + vertexPoints.Add(newVertex); + vertexRoles.Add(Roles.NewAlt); + newInnerVertices[edge.Name] = vertexIndex++; + edge = edge.Next; + } + + if (face.Sides > 2) + { + var innerFace = new int[face.Sides * 2]; + edge = face.Halfedge; + for (int i = 0; i < face.Sides; i++) + { + innerFace[i * 2] = newInnerVertices[edge.Name]; + innerFace[i * 2 + 1] = existingVertices[edge.Vertex.Position]; + edge = edge.Next; + } + + faceIndices.Add(innerFace); + faceRoles.Add(Roles.Existing); + newFaceTags.Add(prevFaceTagSet); + } + } + + var edgeFlags = new HashSet<(Guid, Guid)?>(); + foreach (var edge in Halfedges) + { + if (edge.Pair == null) continue; + + if (!edgeFlags.Contains(edge.PairedName)) + { + var quad = new[] + { + existingVertices[edge.Vertex.Position], + newInnerVertices[edge.Name], + existingVertices[edge.Pair.Vertex.Position], + newInnerVertices[edge.Pair.Name], + }; + faceIndices.Add(quad); + faceRoles.Add(Roles.New); + edgeFlags.Add(edge.PairedName); + + var newFaceTagSet = new HashSet(); + newFaceTagSet.UnionWith(FaceTags[Faces.IndexOf(edge.Face)]); + newFaceTagSet.UnionWith(FaceTags[Faces.IndexOf(edge.Pair.Face)]); + newFaceTags.Add(newFaceTagSet); + } + } + + return new PolyMesh(vertexPoints, faceIndices, faceRoles, vertexRoles, newFaceTags); + } + + public PolyMesh JoinKisKis(OpParams o) { var newFaceTags = new List>(); diff --git a/Packages/Polyhydra/com.ixxy.polyhydra/Core/Runtime/PolyMesh.cs b/Packages/Polyhydra/com.ixxy.polyhydra/Core/Runtime/PolyMesh.cs index ca6336e..a3126fd 100644 --- a/Packages/Polyhydra/com.ixxy.polyhydra/Core/Runtime/PolyMesh.cs +++ b/Packages/Polyhydra/com.ixxy.polyhydra/Core/Runtime/PolyMesh.cs @@ -1294,6 +1294,7 @@ public enum Operation Ortho3 = 97, Zellige = 114, Girih = 110, + Valletta = 115, StraightSkeleton = 105, FaceTessellate = 106, Tessellate = 107, @@ -1494,7 +1495,10 @@ public PolyMesh AppyOperation(Operation op, OpParams p) polyMesh = polyMesh.Stake(p); break; case Operation.JoinStake: - polyMesh = polyMesh.Stake(p, @join: true); + polyMesh = polyMesh.Stake(p, join: true); + break; + case Operation.Valletta: + polyMesh = polyMesh.Valletta(p); break; case Operation.Medial: polyMesh = polyMesh.Medial(p);