public TruncateGeometryOperation(Geometry src, bool close) { Source = src; // Pass 1: Create truncated versions of old polygons foreach (Polygon oldPolygon in Source.Polygons) { Polygon newPolygon = MakeNewPolygonFromPolygon(oldPolygon); double n1 = (double)(oldPolygon.Corners.Count); double n2 = (double)(2 * oldPolygon.Corners.Count); float ratio = (float)(System.Math.Tan(System.Math.PI / n2) / System.Math.Tan(System.Math.PI / n1)); float t = 0.5f - 0.5f * ratio; // Pass 1A: Create truncated corners for (int i = 0; i < oldPolygon.Corners.Count; ++i) { Corner oldCorner = oldPolygon.Corners[i]; Corner nextCorner = oldPolygon.Corners[(i + 1) % oldPolygon.Corners.Count]; UpdateTruncatedEdge(newPolygon, oldCorner, nextCorner, t); } // Pass 1B: Collect open edges from new polygon to per point dictionary // Note the order of points in new edge is important in this case. for (int i = 0; i < newPolygon.Corners.Count; i += 2) { Corner newCorner = newPolygon.Corners[i]; Corner previousCorner = newPolygon.Corners[(i + newPolygon.Corners.Count - 1) % newPolygon.Corners.Count]; Point newPoint = newCorner.Point; Point previousPoint = previousCorner.Point; Point oldPoint = newPointToOld[newPoint]; Edge newEdge = new Edge(newPoint, previousPoint); if (oldPointToOpenEdges.ContainsKey(oldPoint) == false) { oldPointToOpenEdges[oldPoint] = new List <Edge>(); } oldPointToOpenEdges[oldPoint].Add(newEdge); } } // Pass 2: Connect open edges if (close) { foreach (Point oldPoint in src.Points) { if (oldPointToOpenEdges.ContainsKey(oldPoint) == false) { continue; } if (oldPointToOpenEdges[oldPoint].Count < 3) { continue; } Polygon newPolygon = Destination.MakePolygon(); // TODO This polygon has no sources.. inherit average of surrounding polygons? Edge edge = oldPointToOpenEdges[oldPoint].First(); Edge startEdge = edge; // TODO MUSTFIX This loop does not terminate for some geometries // such as tetrahemihexahedron do { bool nextEdgeFound = false; int edgeIndex = 0; foreach (Edge nextEdge in oldPointToOpenEdges[oldPoint]) { ++edgeIndex; if (nextEdge.A == edge.B) { Point newPoint = edge.A; Corner newCorner = newPolygon.MakeCorner(newPoint); DistributeCornerSources(newCorner, 1.0f, newPoint); edge = nextEdge; nextEdgeFound = true; break; } } /* This can happen */ if (nextEdgeFound == false) { break; } }while(edge.Equals(startEdge) == false); if (newPolygon.Corners.Count < 3) { Destination.RemovePolygon(newPolygon); } } } Destination.BuildEdges(); InterpolateAllAttributeMaps(); }
public void RemoveCorner(Corner corner) { corner.Point.Corners.Remove(corner); corners.Remove(corner); }