コード例 #1
0
        internal static bool ChamferPolygons(List <Polygon> polygons, List <Edge> edges, float distance, int iterations, out List <Polygon> resultPolygons)
        {
            // list of clipping planes.
            List <Plane> clippingPlanes = new List <Plane>();

            // iterate through all edges and calculate the clipping planes.
            for (int e = 0; e < edges.Count; e++)
            {
                Edge edge = edges[e];

                // find the two polygons connected to the edge.
                Polygon[] matchingPolygons = polygons.Where(p => Polygon.ContainsEdge(p, edge)).ToArray();
                if (matchingPolygons.Length != 2)
                {
                    resultPolygons = null; return(false);
                }
                ;

                // find the actual edges on the polygons (which helps determine their direction for the chamfer).
                Edge realEdge1;
                Polygon.FindEdge(matchingPolygons[0], edge, out realEdge1);
                Edge realEdge2;
                Polygon.FindEdge(matchingPolygons[1], edge, out realEdge2);

                // calculate clipping plane position:
                Vector3 v1 = realEdge1.Vertex1.Position - ChamferPolygons_GetNormal(realEdge1.Vertex1.Position, realEdge1.Vertex2.Position, matchingPolygons[0].GetCenterPoint()).normalized *distance;
                Vector3 v2 = realEdge1.Vertex2.Position - ChamferPolygons_GetNormal(realEdge1.Vertex1.Position, realEdge1.Vertex2.Position, matchingPolygons[0].GetCenterPoint()).normalized *distance;
                Vector3 v3 = realEdge2.Vertex2.Position - ChamferPolygons_GetNormal(realEdge2.Vertex1.Position, realEdge2.Vertex2.Position, matchingPolygons[1].GetCenterPoint()).normalized *distance;

                for (int i = 0; i < iterations; i++)
                {
                    float   t  = (1.0f / iterations);
                    Vector3 p1 = ShapeEditor.Bezier.GetPoint(v1, realEdge1.Vertex1.Position, v3, t * i);
                    Vector3 p2 = ShapeEditor.Bezier.GetPoint(v1, realEdge1.Vertex1.Position, v3, t * (i + 1));
                    clippingPlanes.Add(new Plane(
                                           p1,
                                           p2,
                                           p1 + (v1 - v2).normalized
                                           ));
                }
            }

            // copy the input polygons.
            resultPolygons = polygons.DeepCopy();

            // clip the polygons.
            for (int i = 0; i < clippingPlanes.Count; i++)
            {
                List <Polygon> polygonsFront;
                List <Polygon> polygonsBack;
                if (SplitPolygonsByPlane(resultPolygons, clippingPlanes[i], false, out polygonsFront, out polygonsBack))
                {
                    resultPolygons = polygonsFront;
                }
            }

            return(true);
        }
コード例 #2
0
        public static bool SplitPolygonsByEdges(Polygon[] polygons, List <Edge> sourceEdges, out Polygon[] finalPolygons, out List <Edge> newEdges)
        {
            // First of all refine the list of edges to those that are on the polygons and share a polygon with another specified edge
            // Verification step, no more than two edges should be selected per face

            // Once the list of edges is refined, walk through each set of polygons
            // Where a polygon has two specified edges, it needs to be split in two
            // Where a polygon has one specified edge, it needs a vertex to be added
            List <Polygon> newPolygons = new List <Polygon>(polygons); // Complete set of new polygons

            newEdges = new List <Edge>();                              // These are the new edges we create

            List <Edge> edges = new List <Edge>();

            // Pull out a list of edges that occur on any of the polygons at least twice.
            // This way we ignore edges on other brushes or edges which aren't possible to connect via a polygon
            for (int edge1Index = 0; edge1Index < sourceEdges.Count; edge1Index++)
            {
                bool found = false;

                for (int i = 0; i < polygons.Length && !found; i++)
                {
                    Edge edge1 = sourceEdges[edge1Index];

                    for (int edge2Index = 0; edge2Index < sourceEdges.Count && !found; edge2Index++)
                    {
                        if (edge2Index != edge1Index)                        // Skip the same edge
                        {
                            Edge edge2 = sourceEdges[edge2Index];

                            bool edge1Contained = Polygon.ContainsEdge(polygons[i], edge1);
                            bool edge2Contained = Polygon.ContainsEdge(polygons[i], edge2);

                            if (edge1Contained && edge2Contained)
                            {
                                if (!edges.Contains(edge1))
                                {
                                    edges.Add(edge1);
                                }

                                if (!edges.Contains(edge2))
                                {
                                    edges.Add(edge2);
                                }
                                found = true;
                            }
                        }
                    }
                }
            }

            // Now process each polygon
            for (int i = 0; i < polygons.Length; i++)
            {
                Polygon polygon = polygons[i];

                List <Edge> edgesOnPolygon = new List <Edge>();
                for (int edgeIndex = 0; edgeIndex < edges.Count; edgeIndex++)
                {
                    Edge edge = edges[edgeIndex];
                    if (Polygon.ContainsEdge(polygon, edge))
                    {
                        edgesOnPolygon.Add(edge);
                    }
                }

                if (edgesOnPolygon.Count == 1)
                {
                    Vertex newVertex;
                    // Add vertex
                    if (!SplitPolygonAtEdge(polygon, edgesOnPolygon[0], out newVertex))
                    {
                        Debug.LogError("Could not add vertex to adjacent polygon");
                    }
                }
                else if (edgesOnPolygon.Count == 2)
                {
                    // Split into two
                    Edge edge1 = edgesOnPolygon[0];
                    Edge edge2 = edgesOnPolygon[1];

                    // First split the shared polygon
                    Vector3 edge1Center = edge1.GetCenterPoint();
                    Vector3 edge2Center = edge2.GetCenterPoint();

                    Vector3 thirdPoint = edge1Center + polygon.Plane.normal;

                    Plane splitPlane = new Plane(edge1Center, edge2Center, thirdPoint);

                    Polygon splitPolygon1;
                    Polygon splitPolygon2;
                    Vertex  edge1Vertex;
                    Vertex  edge2Vertex;

                    Polygon.SplitPolygon(polygon, out splitPolygon1, out splitPolygon2, out edge1Vertex, out edge2Vertex, splitPlane);

                    newEdges.Add(new Edge(edge1Vertex, edge2Vertex));
                    newPolygons.Remove(polygon);
                    newPolygons.Add(splitPolygon1);
                    newPolygons.Add(splitPolygon2);
                }
            }

            finalPolygons = newPolygons.ToArray();

            return(true);
        }