예제 #1
0
    static private Slice2D SliceWithTwoHoles(Polygon polygon, List <Vector2f> slice, List <Vector2f> collisionSlice)
    {
        Slice2D result = Slice2D.Create();

        Polygon polyA = new Polygon();
        Polygon polyB = new Polygon(polygon.pointsList);

        Polygon holeA = polygon.PointInHole(slice.First());
        Polygon holeB = polygon.PointInHole(slice.Last());

        if (holeA == null || holeB == null)
        {
            Debug.LogError("Slicer2D: ERROR Split");              // Shouldn't really happen
            return(result);
        }

        List <Vector2f> pointsA = VectorList2f.GetListStartingIntersectSlice(holeA.pointsList, slice);
        List <Vector2f> pointsB = VectorList2f.GetListStartingIntersectSlice(holeB.pointsList, slice);

        polyA.AddPoints(pointsA);

        if (collisionSlice.Count > 0)
        {
            if (Vector2f.Distance(pointsA.Last(), collisionSlice.Last()) < Vector2f.Distance(pointsA.Last(), collisionSlice.First()))
            {
                collisionSlice.Reverse();
            }

            polyA.AddPoints(collisionSlice);
        }

        polyA.AddPoints(pointsB);

        if (collisionSlice.Count > 0)
        {
            collisionSlice.Reverse();

            polyA.AddPoints(collisionSlice);
        }

        foreach (Polygon poly in polygon.holesList)
        {
            if (poly != holeA && poly != holeB)
            {
                polyB.AddHole(poly);
            }
        }

        polyB.AddHole(polyA);
        result.AddPolygon(polyB);

        return(result);
    }
예제 #2
0
        protected override Polygon GetPolygon()
        {
            Polygon poly = new Polygon(GetPoints());

            if (thickness > 1)
            {
                List <PolygonPoint> points = GetPoints();
                Vector2             center = GetCentroid(points);
                float[]             angles = { TriangleHelper2D.AngleA(a, b, c), TriangleHelper2D.AngleB(a, b, c), TriangleHelper2D.AngleC(a, b, c) };
                int count = points.Count;

                for (int i = count; --i >= 0;)
                {
                    PolygonPoint point = points[i];

                    double vecX   = center.X - point.X;
                    double vecY   = center.Y - point.Y;
                    double invLen = 1d / Math.Sqrt((vecX * vecX) + (vecY * vecY));
                    vecX = vecX * invLen;
                    vecY = vecY * invLen;

                    float ratio          = 1 - (angles[i] / 180);
                    float angleThickness = ratio * thickness;
                    point.X += vecX * angleThickness;
                    point.Y += vecY * angleThickness;
                }

                Polygon hole = new Polygon(points);
                poly.AddHole(hole);
            }

            return(poly);
        }
 internal static Polygon ToP2TPolygon(this PolygonShape p_polygon, List <PolygonShape> p_holes = null)
 {
     if (p_polygon != null && p_polygon.Vertices.Count > 2)
     {
         List <PolygonPoint> v_P2TPoints = new List <PolygonPoint>();
         foreach (var v_vertice in p_polygon.Vertices)
         {
             v_P2TPoints.Add(new PolygonPoint(v_vertice.x, v_vertice.y));
         }
         Polygon v_P2TPolygon = new Polygon(v_P2TPoints);
         if (p_holes != null)
         {
             foreach (var v_hole in p_holes)
             {
                 if (v_hole != null)
                 {
                     var v_P2THole = ToP2TPolygon(v_hole);
                     if (v_P2THole != null)
                     {
                         v_P2TPolygon.AddHole(v_P2THole);
                     }
                 }
             }
         }
         return(v_P2TPolygon);
     }
     return(null);
 }
예제 #4
0
    static private Polygon CreateFromPolygonCollider(PolygonCollider2D polygonCollider)
    {
        Polygon newPolygon = new Polygon();

        if (polygonCollider != null)
        {
            foreach (Vector2 p in polygonCollider.GetPath(0))
            {
                newPolygon.AddPoint(p + polygonCollider.offset);
            }

            for (int i = 1; i < polygonCollider.pathCount; i++)
            {
                Polygon hole = new Polygon();
                foreach (Vector2 p in polygonCollider.GetPath(i))
                {
                    hole.AddPoint(p + polygonCollider.offset);
                }

                if (newPolygon.PolyInPoly(hole) == true)
                {
                    newPolygon.AddHole(hole);
                }
                else
                {
                    Debug.LogError("Path is not a hole");
                }
            }
        }
        return(newPolygon);
    }
        /// <summary>
        /// Given a set of points ordered counter-clockwise along a contour and a set of holes, return triangle indexes.
        /// </summary>
        /// <param name="points"></param>
        /// <param name="holes"></param>
        /// <param name="indexes">Indices outside of the points list index into holes when layed out linearly.
        /// {vertices 0,1,2...vertices.length-1, holes 0 values, hole 1 values etc.} </param>
        /// <returns></returns>
        public static bool Triangulate(IList <Vector2> points, IList <IList <Vector2> > holes, out List <int> indexes)
        {
            indexes = new List <int>();

            int index = 0;

            var allPoints = new List <Vector2>(points);

            Polygon polygon = new Polygon(points.Select(x => new PolygonPoint(x.x, x.y, index++)));

            if (holes != null)
            {
                for (int i = 0; i < holes.Count; i++)
                {
                    allPoints.AddRange(holes[i]);
                    var holePolgyon = new Polygon(holes[i].Select(x => new PolygonPoint(x.x, x.y, index++)));
                    polygon.AddHole(holePolgyon);
                }
            }

            try
            {
                P2T.Triangulate(TriangulationAlgorithm.DTSweep, polygon);
            }
            catch (System.Exception e)
            {
                Log.Info("Triangulation failed: " + e.ToString());
                return(false);
            }

            foreach (DelaunayTriangle d in polygon.Triangles)
            {
                if (d.Points[0].Index < 0 || d.Points[1].Index < 0 || d.Points[2].Index < 0)
                {
                    Log.Info("Triangulation failed: Additional vertices were inserted.");
                    return(false);
                }

                indexes.Add(d.Points[0].Index);
                indexes.Add(d.Points[1].Index);
                indexes.Add(d.Points[2].Index);
            }

            WindingOrder originalWinding = SurfaceTopology.GetWindingOrder(points);

            // if the re-triangulated first tri doesn't match the winding order of the original
            // vertices, flip 'em

            if (SurfaceTopology.GetWindingOrder(new Vector2[3]
            {
                allPoints[indexes[0]],
                allPoints[indexes[1]],
                allPoints[indexes[2]],
            }) != originalWinding)
            {
                indexes.Reverse();
            }

            return(true);
        }
예제 #6
0
    static private Slice2D SlicePolygonInside(Polygon polygon, List <Vector2f> slice)    // Create Polygon Inside?
    {
        Slice2D result = Slice2D.Create();

        Polygon newPoly = new Polygon();

        bool createPoly = false;

        foreach (Pair2f pairA in Pair2f.GetList(slice, false))
        {
            foreach (Pair2f pairB in Pair2f.GetList(slice, false))
            {
                Vector2f intersection = MathHelper.GetPointLineIntersectLine(pairA, pairB);
                if (intersection != null && (pairA.A != pairB.A && pairA.B != pairB.B && pairA.A != pairB.B && pairA.B != pairB.A))
                {
                    createPoly = !createPoly;
                    newPoly.AddPoint(intersection);
                }
            }
            if (createPoly == true)
            {
                newPoly.AddPoint(pairA.B);
            }
        }

        bool inHoles = false;

        foreach (Polygon hole in polygon.holesList)
        {
            if (hole.PolyInPoly(newPoly) == true)
            {
                inHoles = true;
            }
        }

        if (inHoles == false && newPoly.pointsList.Count > 2 && polygon.PolyInPoly(newPoly) == true)
        {
            polygon.AddHole(newPoly);
            List <Polygon> polys = new List <Polygon> (polygon.holesList);
            foreach (Polygon hole in polys)
            {
                if (newPoly.PolyInPoly(hole) == true)
                {
                    polygon.holesList.Remove(hole);
                    newPoly.AddHole(hole);
                }
            }

            result.AddPolygon(polygon);
            if (Slicer2D.complexSliceType == Slicer2D.SliceType.FillSlicedHole)
            {
                result.AddPolygon(newPoly);
            }

            return(result);
        }

        return(result);
    }
예제 #7
0
        /*! \cond PRIVATE */

        bool triangulate()
        {
            if (Outline == null || Outline.Spline == null)
            {
                Error = "Missing Outline Spline";
                return(false);
            }
            if (!polyLineIsValid(Outline))
            {
                Error = Outline.Spline.name + ": Angle must be >0";
                return(false);
            }

            Vector3[] outlineVerts = Outline.getVertices();
            if (outlineVerts.Length < 3)
            {
                Error = Outline.Spline.name + ": At least 3 Vertices needed!";
                return(false);
            }
            p2t = new Polygon(outlineVerts);

            if (VertexLineOnly)
            {
                return(true);
            }

            for (int i = 0; i < Holes.Count; i++)
            {
                if (Holes[i].Spline == null)
                {
                    Error = "Missing Hole Spline";
                    return(false);
                }
                if (!polyLineIsValid(Holes[i]))
                {
                    Error = Holes[i].Spline.name + ": Angle must be >0";
                    return(false);
                }
                Vector3[] verts = Holes[i].getVertices();
                if (verts.Length < 3)
                {
                    Error = Holes[i].Spline.name + ": At least 3 Vertices needed!";
                    return(false);
                }
                p2t.AddHole(new Polygon(verts));
            }
            try
            {
                P2T.Triangulate(p2t);
                return(true);
            }
            catch (System.Exception e)
            {
                Error = e.Message;
            }

            return(false);
        }
        protected override void OnUpdate()
        {
            Polygon poly  = null;
            var     holes = new List <Polygon>();

            Entities.ForEach((ref PolygonOrientationComponent polygonOrientation, DynamicBuffer <PointSampleGlobal> points) =>
            {
                PolygonPoint[] pointArray = new PolygonPoint[points.Length];
                for (var i = 0; i < points.Length; i++)
                {
                    pointArray[i] = new PolygonPoint(points[i].pose.pos.x, points[i].pose.pos.z);
                }
                var polygon = new Polygon(pointArray);
                if (polygonOrientation.Orientation == PolygonOrientation.Outside)
                {
                    if (poly != null)
                    {
                        Debug.LogError("Multiple outside polygons detected. " +
                                       "Multiple outside polygons indicate a disconnected road network.");
                    }
                    poly = polygon;
                }
                else
                {
                    holes.Add(polygon);
                }
            });

            if (poly == null)
            {
                throw new NullReferenceException($"Polygon is null - will be unable to create mesh for " +
                                                 $"{Parameters.Parent.name}.");
            }

            foreach (var hole in holes)
            {
                poly.AddHole(hole);
            }

            var mesh = RoadNetworkMesher.PolygonToMesh(poly, Parameters.UVMultiplier);

            GameObject go = new GameObject("Road mesh");

            go.transform.parent        = Parameters.Parent;
            go.transform.localPosition = new Vector3(0, .1f, 0);
            var meshRenderer = go.AddComponent <MeshRenderer>();

            meshRenderer.material = Parameters.Material;
            var meshFilter = go.AddComponent <MeshFilter>();

            meshFilter.mesh = mesh;
            go.AddComponent <MeshCollider>();
        }
예제 #9
0
        protected virtual Polygon GetPolygon()
        {
            Polygon poly = new Polygon(GetPoints());

            if (thickness > 0)
            {
                Polygon hole = new Polygon(GetPoints(thickness));
                poly.AddHole(hole);
            }

            return(poly);
        }
예제 #10
0
    public Polygon ToLocalSpace(Transform transform)
    {
        Polygon newPolygon = new Polygon();

        foreach (Vector2f id in pointsList)
        {
            newPolygon.AddPoint(transform.InverseTransformPoint(id.Get()));
        }

        foreach (Polygon p in holesList)
        {
            newPolygon.AddHole(p.ToLocalSpace(transform));
        }

        return(newPolygon);
    }
예제 #11
0
    public Polygon ToOffset(Vector2f pos)
    {
        Polygon newPolygon = new Polygon(pointsList);

        foreach (Vector2f p in newPolygon.pointsList)
        {
            p.Inc(pos);
        }

        foreach (Polygon p in holesList)
        {
            newPolygon.AddHole(p.ToOffset(pos));
        }

        return(newPolygon);
    }
예제 #12
0
        protected override Polygon GetPolygon()
        {
            Polygon poly = new Polygon(GetPoints());

            if (thickness > 0)
            {
                List <PolygonPoint> holePoints = new List <PolygonPoint>()
                {
                    new PolygonPoint(thickness, thickness),
                    new PolygonPoint(width - thickness, thickness),
                    new PolygonPoint(width - thickness, height - thickness),
                    new PolygonPoint(thickness, height - thickness)
                };

                Polygon hole = new Polygon(holePoints);
                poly.AddHole(hole);
            }

            return(poly);
        }
    /// <summary>
    /// Creates a triangulation of the vertices given, and gives you the indices of it.
    /// </summary>
    /// <param name="aPoints">A list of points to triangulate.</param>
    /// <param name="aTreatAsPath">Should we discard any triangles at all? Use this if you want to get rid of triangles that are outside the path.</param>
    /// <param name="aInvert">if we're treating it as a path, should we instead sicard triangles inside the path?</param>
    /// <param name="aInvertBorderSize">When inverted, how large should the border be in each direction?</param>
    /// <returns>A magical list of indices describing the triangulation!</returns>
    public static List <int> GetIndices(ref List <Vector2> aPoints, bool aTreatAsPath, bool aInvert, Vector2 aInvertBorderSize, float aVertGridSpacing = 0)
    {
        Vector4 bounds = GetBounds(aPoints);

        if (aVertGridSpacing > 0)
        {
            SplitEdges(ref aPoints, aVertGridSpacing);
        }

        List <PolygonPoint> verts = new List <PolygonPoint>(aPoints.Count);

        for (int i = 0; i < aPoints.Count; i++)
        {
            verts.Add(new PolygonPoint(aPoints[i].x, aPoints[i].y));
        }

        Polygon poly;

        if (aInvert)
        {
            float width  = aInvertBorderSize.x == 0 ? (bounds.z - bounds.x) : aInvertBorderSize.x;
            float height = aInvertBorderSize.y == 0 ? (bounds.y - bounds.w) : aInvertBorderSize.y;
            aPoints.Add(new Vector2(bounds.x - width, bounds.w - height));
            aPoints.Add(new Vector2(bounds.z + width, bounds.w - height));
            aPoints.Add(new Vector2(bounds.z + width, bounds.y + height));
            aPoints.Add(new Vector2(bounds.x - width, bounds.y + height));

            List <PolygonPoint> outer = new List <PolygonPoint>(4);
            for (int i = 0; i < 4; i++)
            {
                outer.Add(new PolygonPoint(aPoints[(aPoints.Count - 4) + i].x, aPoints[(aPoints.Count - 4) + i].y));
            }
            poly = new Polygon(outer);
            poly.AddHole(new Polygon(verts));
        }
        else
        {
            poly = new Polygon(verts);
        }

        if (aVertGridSpacing > 0)
        {
            if (aInvert)
            {
                bounds = GetBounds(aPoints);
            }
            for (float y = bounds.w + aVertGridSpacing; y <= bounds.y; y += aVertGridSpacing)
            {
                for (float x = bounds.x + aVertGridSpacing; x <= bounds.z; x += aVertGridSpacing)
                {
                    TriangulationPoint pt = new TriangulationPoint(x, y);
                    bool inside           = poly.IsPointInside(pt);
                    if (inside)
                    {
                        poly.AddSteinerPoint(pt);
                    }
                }
            }
        }
        P2T.Triangulate(poly);

        aPoints.Clear();
        List <int> result = new List <int>(poly.Triangles.Count * 3);
        int        ind    = 0;

        foreach (DelaunayTriangle triangle in poly.Triangles)
        {
            TriangulationPoint p1 = triangle.Points[0];
            TriangulationPoint p2 = triangle.PointCWFrom(p1);
            TriangulationPoint p3 = triangle.PointCWFrom(p2);

            aPoints.Add(new Vector2(p1.Xf, p1.Yf));
            aPoints.Add(new Vector2(p2.Xf, p2.Yf));
            aPoints.Add(new Vector2(p3.Xf, p3.Yf));
            result.Add(ind++);
            result.Add(ind++);
            result.Add(ind++);
        }
        return(result);
    }
예제 #14
0
 public static void TriangulateWithHoles(ArrayList vectors, List <ArrayList> holes, ref Mesh mesh, bool ceiling, bool twoSided, float y)
 {
     if (vectors.Count >= 3)
     {
         PolygonPoint[] c           = new PolygonPoint[vectors.Count];
         List <Vector3> list        = new List <Vector3>();
         Vector2[]      vectorArray = new Vector2[vectors.Count];
         List <int>     list2       = null;
         for (int i = 0; i < vectors.Count; i++)
         {
             Vector2 vector = (Vector2)vectors[i];
             c[i] = new PolygonPoint((double)vector.x, (double)vector.y);
             list.Add(new Vector3(vector.x, y, vector.y));
             vectorArray[i] = new Vector2(vector.x, vector.y);
         }
         ArrayList list3 = new ArrayList(c);
         Polygon   p     = new Polygon(c);
         foreach (ArrayList list4 in holes)
         {
             List <PolygonPoint> list5 = new List <PolygonPoint>();
             for (int k = 0; k < list4.Count; k++)
             {
                 Vector2 vector2 = (Vector2)list4[k];
                 list5.Add(new PolygonPoint((double)vector2.x, (double)vector2.y));
                 list.Add(new Vector3(vector2.x, y, vector2.y));
             }
             list3.AddRange(list5);
             p.AddHole(new Polygon(list5));
         }
         P2T.Triangulate(p);
         list2 = new List <int>();
         for (int j = 0; j < p.Triangles.Count; j++)
         {
             if (twoSided)
             {
                 list2.Add(list3.IndexOf(p.Triangles[j].Points._2));
                 list2.Add(list3.IndexOf(p.Triangles[j].Points._1));
                 list2.Add(list3.IndexOf(p.Triangles[j].Points._0));
                 list2.Add(list3.IndexOf(p.Triangles[j].Points._0));
                 list2.Add(list3.IndexOf(p.Triangles[j].Points._1));
                 list2.Add(list3.IndexOf(p.Triangles[j].Points._2));
             }
             else if (!ceiling)
             {
                 list2.Add(list3.IndexOf(p.Triangles[j].Points._2));
                 list2.Add(list3.IndexOf(p.Triangles[j].Points._1));
                 list2.Add(list3.IndexOf(p.Triangles[j].Points._0));
             }
             else
             {
                 list2.Add(list3.IndexOf(p.Triangles[j].Points._0));
                 list2.Add(list3.IndexOf(p.Triangles[j].Points._1));
                 list2.Add(list3.IndexOf(p.Triangles[j].Points._2));
             }
         }
         list2.TrimExcess();
         list.TrimExcess();
         mesh.vertices  = list.ToArray();
         mesh.triangles = list2.ToArray();
         mesh.RecalculateBounds();
     }
 }
예제 #15
0
        bool triangulate()
        {
            if (Outline == null || Outline.Spline == null) {
                Error = "Missing Outline Spline";
                return false;
            }
            if (!polyLineIsValid(Outline)){
                Error=Outline.Spline.name+": Angle must be >0";
                return false;
            }

            Vector3[] outlineVerts = Outline.getVertices();
            if (outlineVerts.Length < 3) {
                Error=Outline.Spline.name+": At least 3 Vertices needed!";
                return false;
            }
            p2t = new Polygon(outlineVerts);

            if (VertexLineOnly)
                return true;

            for (int i = 0; i < Holes.Count; i++) {
                if (Holes[i].Spline == null) {
                    Error = "Missing Hole Spline";
                    return false;
                }
                if (!polyLineIsValid(Holes[i])) {
                    Error = Holes[i].Spline.name + ": Angle must be >0";
                    return false;
                }
                Vector3[] verts=Holes[i].getVertices();
                if (verts.Length<3){
                    Error=Holes[i].Spline.name+": At least 3 Vertices needed!";
                    return false;
                }
                p2t.AddHole(new Polygon(verts));
            }
            try {
                P2T.Triangulate(p2t);
                return true;
            }
            catch (System.Exception e) {
                Error = e.Message;
            }

            return false;
        }
예제 #16
0
        public static Mesh triangulate(AXSpline poly, float height, AXTexCoords tex)
        {
            // poly has verts that are delimeted by 8888888 for holes

            //Debug.Log ("F");
            // 1. transpose points to poly2tri structures
            // 2. create mesh
            Polygon _polygon = null;

            List <AXSpline> parts = poly.getSolidAndHoles();

            if (parts == null || parts.Count == 0)
            {
                return(null);
            }

            // CONTOUR
            AXSpline contour = parts[0];

            List <PolygonPoint> _points = new List <PolygonPoint>();

            for (int ii = 0; ii < contour.vertCount; ii++)
            {
                _points.Add(new PolygonPoint((double)contour.verts[ii].x, (double)contour.verts[ii].y));
            }


            // POLYGON
            if (_points.Count >= 3)
            {
                _polygon = new Polygon(_points);


                // HOLES?
                if (parts.Count > 1)
                {
                    for (int i = 1; i < parts.Count; i++)
                    {
                        List <PolygonPoint> _holepoints = new List <PolygonPoint>();
                        for (int ii = 0; ii < parts[i].vertCount; ii++)
                        {
                            _holepoints.Add(new PolygonPoint((double)parts[i].verts[ii].x, (double)parts[i].verts[ii].y));
                        }
                        if (_holepoints.Count >= 3)
                        {
                            Polygon _hole = new Polygon(_holepoints);
                            _polygon.AddHole(_hole);
                        }
                    }
                }
            }

            // populate the polygon triangles
            if (_polygon != null)
            {
                P2T.Triangulate(_polygon);

                return(polygon2mesh(_polygon, tex));
            }
            return(null);
        }
예제 #17
0
    public void addHoles(List <Hole> holes)
    {
        Mesh           mesh            = GetComponent <MeshFilter>().mesh;
        List <Vector2> rectanglePoints = new List <Vector2> ();

        rectanglePoints.Add(new Vector2(0, 0));
        rectanglePoints.Add(new Vector2(0, height));
        rectanglePoints.Add(new Vector2(length, height));
        rectanglePoints.Add(new Vector2(length, 0));
        latest_face = createPoly(rectanglePoints.ToArray());

        for (int l = 0; l < holes.Count; l++)
        {
            Debug.Log(holes[l].Position);
        }

        for (int k = 0; k < holes.Count; k++)
        {
            float distance = (holes[k].Position - this.Start_pt).magnitude;
            hole_length    = holes [k].Hole_length;
            hole_height    = holes [k].Hole_height;
            hole_elevation = holes [k].Hole_elevation;
            //distance = 1;

            if (distance > (length - hole_length / 2) || distance < hole_length / 2)
            {
                Debug.Log("Hole exceeds " + this.name + " by " + distance);
            }
            else
            {
                List <Vector2> holePoints = new List <Vector2> ();

                holePoints.Add(new Vector2(distance - hole_length / 2, hole_elevation - hole_height / 2));
                holePoints.Add(new Vector2(distance - hole_length / 2, hole_elevation + hole_height / 2));
                holePoints.Add(new Vector2(distance + hole_length / 2, hole_elevation + hole_height / 2));
                holePoints.Add(new Vector2(distance + hole_length / 2, hole_elevation - hole_height / 2));


                Polygon Hole = createPoly(holePoints.ToArray());
                Debug.Log("Created hole");


                latest_face.AddHole(Hole);

                holes [k].Hole_start_index = (k - 1) >= 0 ? holes [k - 1].Hole_end_index : 4;
                //Debug.Log ("here");
                hole_list.Add(holes [k]);
            }
        } // holes loop end
        print(latest_face);
        P2T.Triangulate(latest_face);
        for (int i = 0; i < latest_face.Triangles.Count; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                TriangulationPoint tpt = latest_face.Triangles [i].Points [j];
                Vector3            pt  = new Vector3(-thickness / 2, (float)tpt.Y, (float)tpt.X);
                new_tris.Add(vertexIndices [pt]);
            }
        }
        mesh.Clear();
        mesh.vertices  = new_verts.ToArray();
        mesh.triangles = new_tris.ToArray();
        mesh           = this.extrudeWall(mesh);
        mesh.RecalculateNormals();
        //PUNEET -> ReAdded Meshcollider to wall in the case of hole
        gameObject.AddMissingComponent <MeshCollider>().sharedMesh = mesh;

        //change uvs according to hole
    }
예제 #18
0
    // Polygon Slice - TODO: Return No Polygon if it's eaten by polygon slice
    static public Slice2D Slice(Polygon polygon, Polygon polygonSlice)
    {
        Slice2D result = Slice2D.Create();

        Slicer2D.SliceType tempSliceType = Slicer2D.complexSliceType;
        Slicer2D.complexSliceType = Slicer2D.SliceType.SliceHole;

        polygonSlice.Normalize();
        polygon.Normalize();

        // Eat a polygon completely
        // Complex Slicer does not register slice in this case
        if (polygonSlice.PolyInPoly(polygon) == true)
        {
            result.AddPolygon(polygon);
            return(result);
        }

        if (polygon.PolyInPoly(polygonSlice) == true)
        {
            polygon.AddHole(polygonSlice);
            result.AddPolygon(polygon);
            return(result);
        }

        // Act as Regular Slice
        Vector2f startPoint = null;

        foreach (Vector2f id in polygonSlice.pointsList)
        {
            if (polygon.PointInPoly(id) == false)
            {
                startPoint = id;
                break;
            }
        }


        if (startPoint == null)
        {
            Debug.LogError("Slicer2D: Starting Point Error In PolygonSlice");
            return(result);
        }

        polygonSlice.pointsList = VectorList2f.GetListStartingPoint(polygonSlice.pointsList, startPoint);

        /*
         * List<Vector2f> s = new List<Vector2f> ();
         * foreach (Pair2f pair in Pair2f.GetList(polygonSlice.pointsList, false)) {
         *      List<Vector2f> stackList = polygon.GetListSliceIntersectPoly(pair);
         *      stackList = VectorList2f.GetListSortedToPoint (stackList, pair.A);
         *      Vector2f old = pair.A;
         *      s.Add (old);
         *
         *      foreach (Vector2f id in stackList) {
         *              s.Add (new Vector2f((old.GetX() + id.GetX()) / 2, (old.GetY() + id.GetY()) / 2));
         *              old = id;
         *      }
         * }
         *
         * polygonSlice.pointsList = s;
         */

        polygonSlice.AddPoint(startPoint);

        // Not necessary
        if (polygon.SliceIntersectPoly(polygonSlice.pointsList) == false)
        {
            return(result);
        }

        // Slice More Times?
        result = ComplexSlicer.Slice(polygon, new List <Vector2f> (polygonSlice.pointsList));

        if (result.polygons.Count < 1)
        {
            Debug.LogError("Slicer2D: Returns Empty Polygon Slice");
        }

        Slicer2D.complexSliceType = tempSliceType;

        return(result);
    }
예제 #19
0
        /*! \endcond */
        #endregion

        #region ### Public Methods ###

        public override void Refresh()
        {
            base.Refresh();
            CGVolume vol = InVolume.GetData<CGVolume>();
            var holes = InVolumeHoles.GetAllData<CGVolume>();

            if (vol)
            {
                bool genStart = (StartCap == CGYesNoAuto.Yes || (StartCap == CGYesNoAuto.Auto && !vol.Seamless));
                bool genEnd = (EndCap == CGYesNoAuto.Yes || (EndCap == CGYesNoAuto.Auto && !vol.Seamless));

                if (!genStart && !genEnd)
                {
                    OutVMesh.SetData(null);
                    return;
                }

                var vmesh = new CGVMesh();
                Vector3[] vtStart = new Vector3[0];
                Vector3[] vtEnd = new Vector3[0];



                Polygon pOuter;

                vmesh.AddSubMesh(new CGVSubMesh());
                CGVSubMesh submesh = vmesh.SubMeshes[0];
                Vector3[] points;

                if (genStart)
                {
                    #region --- Start Cap ---
                    points = make2DSegment(vol, 0);
                    if (points.Length < 3)
                    {
                        OutVMesh.SetData(null);
                        UIMessages.Add("Cross has <3 Vertices: Can't create Caps!");
                        return;
                    }

                    pOuter = new Polygon(points);

                    for (int h = 0; h < holes.Count; h++)
                    {
                        points = make2DSegment(holes[h], 0);
                        if (points.Length < 3)
                        {
                            OutVMesh.SetData(null);
                            UIMessages.Add("Hole Cross has <3 Vertices: Can't create Caps!");
                            return;
                        }
                        pOuter.AddHole(new Polygon(points));
                    }

                    try
                    {
                        P2T.Triangulate(pOuter);
                    }
                    catch (System.Exception e)
                    {
                        Debug.LogException(e);
                        OutVMesh.SetData(null);
                        return;
                    }

                    submesh.Material = StartMaterial;
                    pOuter.GetResults(out vtStart, out submesh.Triangles, ReverseTriOrder);
                    vmesh.Vertex = applyMat(vtStart, getMat(vol, 0, true));
                    if (GenerateUV)
                    {
                        vmesh.UV = new Vector2[vtStart.Length];
                        applyUV(vtStart, ref vmesh.UV, 0, vtStart.Length, pOuter.Bounds.Bounds, StartMaterialSettings);
                    }



                    #endregion
                }

                if (genEnd)
                {
                    #region --- End Cap ---

                    points = make2DSegment(vol, vol.Count - 1);
                    if (points.Length < 3)
                    {
                        OutVMesh.SetData(null);
                        UIMessages.Add("Cross has <3 Vertices: Can't create Caps!");
                        return;
                    }
                    pOuter = new Polygon(points);

                    for (int h = 0; h < holes.Count; h++)
                    {
                        points = make2DSegment(holes[h], holes[h].Count - 1);
                        if (points.Length < 3)
                        {
                            OutVMesh.SetData(null);
                            UIMessages.Add("Hole Cross has <3 Vertices: Can't create Caps!");
                            return;
                        }
                        pOuter.AddHole(new Polygon(points));
                    }

                    try
                    {
                        P2T.Triangulate(pOuter);
                    }
                    catch (System.Exception e)
                    {
                        Debug.LogException(e);
                        OutVMesh.SetData(null);
                        return;
                    }

                    int[] tris;
                    pOuter.GetResults(out vtEnd, out tris, !ReverseTriOrder, vtStart.Length);

                    vmesh.Vertex = vmesh.Vertex.AddRange<Vector3>(applyMat(vtEnd, getMat(vol, vol.Count - 1, true)));

                    if (!CloneStartCap && StartMaterial != EndMaterial)
                    {
                        vmesh.AddSubMesh(new CGVSubMesh(tris, EndMaterial));
                    }
                    else
                    {
                        submesh.Material = StartMaterial;
                        submesh.Triangles = submesh.Triangles.AddRange<int>(tris);
                    }

                    if (GenerateUV)
                    {
                        System.Array.Resize<Vector2>(ref vmesh.UV, vmesh.UV.Length + vtEnd.Length);
                        applyUV(vtEnd, ref vmesh.UV, vtStart.Length, vtEnd.Length, pOuter.Bounds.Bounds, (CloneStartCap) ? StartMaterialSettings : EndMaterialSettings);
                    }


                    #endregion
                }


                OutVMesh.SetData(vmesh);
            }
        }