Ejemplo n.º 1
0
 public void InitializeHoles(ConstrainedPointSet cps)
 {
     Contour.InitializeHoles(mHoles, this, cps);
     foreach (Contour c in mHoles)
     {
         c.InitializeHoles(cps);
     }
 }
Ejemplo n.º 2
0
 public static void Triangulate(ConstrainedPointSet cps)
 {
     Triangulate(_defaultAlgorithm, cps);
 }
Ejemplo n.º 3
0
        ////////


        public static PointSet LoadDatPointSet(string filename, bool xflip, bool yflip, bool displayFlipX, bool displayFlipY, float rotateAngleInDegrees)
        {
            var points = new List<TriangulationPoint>();
            List<List<TriangulationPoint>> constrainedPoints = new List<List<TriangulationPoint>>();
            List<string> constrainedPointSetNames = new List<string>();
            List<TriangulationPoint> bounds = new List<TriangulationPoint>();
            List<TriangulationPoint> currentList = points;
            double precision = TriangulationPoint.kVertexCodeDefaultPrecision;
            int lineNum = 0;
            bool skipLine = false;
            foreach (var line_ in File.ReadAllLines(filename))
            {
                ++lineNum;
                string line = line_.Trim();
                if (string.IsNullOrEmpty(line) ||
                    line.StartsWith("//") ||
                    line.StartsWith("#") ||
                    line.StartsWith(";"))
                {
                    continue;
                }
                if (!skipLine && line.StartsWith("/*"))
                {
                    skipLine = true;
                    continue;
                }
                else if (skipLine)
                {
                    if( line.StartsWith("*/"))
                    {
                        skipLine = false;
                    }
                    continue;
                }
                if (line.StartsWith("Precision", StringComparison.InvariantCultureIgnoreCase))
                {
                    if (line.Length > 9)
                    {
                        string precisionStr = line.Substring(9).Trim();
                        if (!double.TryParse(precisionStr, NumberStyles.Float, CultureInfo.InvariantCulture, out precision))
                        {
                            Console.WriteLine("Invalid Precision '" + precisionStr + "' in file " + filename + ", line " + lineNum.ToString() + ".  Setting to " + TriangulationPoint.kVertexCodeDefaultPrecision.ToString());
                            precision = TriangulationPoint.kVertexCodeDefaultPrecision;
                        }
                    }
                }
                else if (line.StartsWith("Set", StringComparison.InvariantCultureIgnoreCase))
                {
                    if (line.StartsWith("SetBegin"))
                    {
                        string[] setParts = line.Split(new[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
                        if (setParts.Length < 2)
                        {
                            continue;
                        }
                        //if (setParts[1].Equals("Constrained", StringComparison.InvariantCultureIgnoreCase))
                        if (setParts[1].Equals("Constrained", StringComparison.InvariantCultureIgnoreCase) ||
                            setParts[1].Equals("Unconstrained", StringComparison.InvariantCultureIgnoreCase))
                        {
                            currentList = new List<TriangulationPoint>();
                            constrainedPoints.Add(currentList);
                            if( setParts.Length>2)
                            {
                                constrainedPointSetNames.Add(setParts[2]);
                            }
                            else
                            {
                                constrainedPointSetNames.Add("");
                            }
                        }
                        else if (bounds.Count == 0 && setParts[1].Equals("Bounds", StringComparison.InvariantCultureIgnoreCase))
                        {
                            currentList = bounds;
                        }
                        else
                        {
                            currentList = points;
                        }
                    }
                    else
                    {
                        currentList = points;
                    }
                }
                else
                {
                    var xy = line.Split(new[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries);
                    double x, y;
                    if (xy != null &&
                        xy.Length >= 2 &&
                        double.TryParse(xy[0], NumberStyles.Float, CultureInfo.InvariantCulture, out x) &&
                        double.TryParse(xy[1], NumberStyles.Float, CultureInfo.InvariantCulture, out y))
                    {
                        currentList.Add(new PolygonPoint((xflip ? -1.0 : 1.0) * x, (yflip ? -1.0 : 1.0) * y));
                    }
                    else
                    {
                        Console.WriteLine("Invalid Input '" + line + "' in file " + filename + ", line " + lineNum.ToString());
                    }
                }
            }

            PointSet ps = null;
            if (constrainedPoints.Count > 0)
            {
                ConstrainedPointSet cps = null;
                if (bounds.Count < 3)
                {
                    points.AddRange(bounds);
                    cps = new ConstrainedPointSet(points);
                }
                else
                {
                    cps = new ConstrainedPointSet(bounds);
                    cps.AddRange(points);
                }
                int numConstrainedPointSets = constrainedPoints.Count;
                for( int i = 0; i < numConstrainedPointSets; ++i)
                {
                    List<TriangulationPoint> hole = constrainedPoints[i];
                    if (hole.Count < 3)
                    {
                        cps.AddRange(hole);
                    }
                    else
                    {
                        cps.AddHole(hole, constrainedPointSetNames[i]);
                    }
                }
                ps = cps;
            }
            else
            {
                if (bounds.Count < 3)
                {
                    points.AddRange(bounds);
                    ps = new PointSet(points);
                }
                else
                {
                    ps = new PointSet(bounds);
                    ps.AddRange(points);
                }
            }

            ps.FileName = filename;
            ps.DisplayFlipX = displayFlipX;
            ps.DisplayFlipY = displayFlipY;
            ps.DisplayRotate = rotateAngleInDegrees;
            ps.Precision = precision;

            return ps;
        }
Ejemplo n.º 4
0
 public static void Triangulate(ConstrainedPointSet cps)
 {
     Triangulate(_defaultAlgorithm, cps);
 }
Ejemplo n.º 5
0
        public static void InitializeHoles(List <Contour> holes, ITriangulatable parent, ConstrainedPointSet cps)
        {
            int numHoles = holes.Count;
            int holeIdx  = 0;

            // pass 1 - remove duplicates
            while (holeIdx < numHoles)
            {
                int hole2Idx = holeIdx + 1;
                while (hole2Idx < numHoles)
                {
                    bool bSamePolygon = PolygonUtil.PolygonsAreSame2D(holes[holeIdx], holes[hole2Idx]);
                    if (bSamePolygon)
                    {
                        // remove one of them
                        holes.RemoveAt(hole2Idx);
                        --numHoles;
                    }
                    else
                    {
                        ++hole2Idx;
                    }
                }
                ++holeIdx;
            }

            // pass 2: Intersections and Containment
            holeIdx = 0;
            while (holeIdx < numHoles)
            {
                bool bIncrementHoleIdx = true;
                int  hole2Idx          = holeIdx + 1;
                while (hole2Idx < numHoles)
                {
                    if (PolygonUtil.PolygonContainsPolygon(holes[holeIdx], holes[holeIdx].Bounds, holes[hole2Idx], holes[hole2Idx].Bounds, false))
                    {
                        holes[holeIdx].AddHole(holes[hole2Idx]);
                        holes.RemoveAt(hole2Idx);
                        --numHoles;
                    }
                    else if (PolygonUtil.PolygonContainsPolygon(holes[hole2Idx], holes[hole2Idx].Bounds, holes[holeIdx], holes[holeIdx].Bounds, false))
                    {
                        holes[hole2Idx].AddHole(holes[holeIdx]);
                        holes.RemoveAt(holeIdx);
                        --numHoles;
                        bIncrementHoleIdx = false;
                        break;
                    }
                    else
                    {
                        bool bIntersect = PolygonUtil.PolygonsIntersect2D(holes[holeIdx], holes[holeIdx].Bounds, holes[hole2Idx], holes[hole2Idx].Bounds);
                        if (bIntersect)
                        {
                            // this is actually an error condition
                            // fix by merging hole1 and hole2 into hole1 (including the holes inside hole2!) and delete hole2
                            // Then, because hole1 is now changed, restart it's check.
                            PolygonOperationContext ctx = new PolygonOperationContext();
                            if (!ctx.Init(PolygonUtil.PolyOperation.Union | PolygonUtil.PolyOperation.Intersect, holes[holeIdx], holes[hole2Idx]))
                            {
                                if (ctx.mError == PolygonUtil.PolyUnionError.Poly1InsidePoly2)
                                {
                                    holes[hole2Idx].AddHole(holes[holeIdx]);
                                    holes.RemoveAt(holeIdx);
                                    --numHoles;
                                    bIncrementHoleIdx = false;
                                    break;
                                }
                                else
                                {
                                    throw new Exception("PolygonOperationContext.Init had an error during initialization");
                                }
                            }
                            PolygonUtil.PolyUnionError pue = PolygonUtil.PolygonOperation(ctx);
                            if (pue == PolygonUtil.PolyUnionError.None)
                            {
                                Point2DList union        = ctx.Union;
                                Point2DList intersection = ctx.Intersect;

                                // create a new contour for the union
                                Contour c = new Contour(parent);
                                c.AddRange(union);
                                c.Name         = "(" + holes[holeIdx].Name + " UNION " + holes[hole2Idx].Name + ")";
                                c.WindingOrder = Point2DList.WindingOrderType.Default;

                                // add children from both of the merged contours
                                int numChildHoles = holes[holeIdx].GetNumHoles();
                                for (int i = 0; i < numChildHoles; ++i)
                                {
                                    c.AddHole(holes[holeIdx].GetHole(i));
                                }
                                numChildHoles = holes[hole2Idx].GetNumHoles();
                                for (int i = 0; i < numChildHoles; ++i)
                                {
                                    c.AddHole(holes[hole2Idx].GetHole(i));
                                }

                                // make sure we preserve the contours of the intersection
                                Contour cInt = new Contour(c);
                                cInt.AddRange(intersection);
                                cInt.Name         = "(" + holes[holeIdx].Name + " INTERSECT " + holes[hole2Idx].Name + ")";
                                cInt.WindingOrder = Point2DList.WindingOrderType.Default;
                                c.AddHole(cInt);

                                // replace the current contour with the merged contour
                                holes[holeIdx] = c;

                                // toss the second contour
                                holes.RemoveAt(hole2Idx);
                                --numHoles;

                                // current hole is "examined", so move to the next one
                                hole2Idx = holeIdx + 1;
                            }
                            else
                            {
                                throw new Exception("PolygonOperation had an error!");
                            }
                        }
                        else
                        {
                            ++hole2Idx;
                        }
                    }
                }
                if (bIncrementHoleIdx)
                {
                    ++holeIdx;
                }
            }

            numHoles = holes.Count;
            holeIdx  = 0;
            while (holeIdx < numHoles)
            {
                int numPoints = holes[holeIdx].Count;
                for (int i = 0; i < numPoints; ++i)
                {
                    int  j = holes[holeIdx].NextIndex(i);
                    uint constraintCode        = TriangulationConstraint.CalculateContraintCode(holes[holeIdx][i], holes[holeIdx][j]);
                    TriangulationConstraint tc = null;
                    if (!cps.TryGetConstraint(constraintCode, out tc))
                    {
                        tc = new TriangulationConstraint(holes[holeIdx][i], holes[holeIdx][j]);
                        cps.AddConstraint(tc);
                    }

                    // replace the points in the holes with valid points
                    if (holes[holeIdx][i].VertexCode == tc.P.VertexCode)
                    {
                        holes[holeIdx][i] = tc.P;
                    }
                    else if (holes[holeIdx][j].VertexCode == tc.P.VertexCode)
                    {
                        holes[holeIdx][j] = tc.P;
                    }
                    if (holes[holeIdx][i].VertexCode == tc.Q.VertexCode)
                    {
                        holes[holeIdx][i] = tc.Q;
                    }
                    else if (holes[holeIdx][j].VertexCode == tc.Q.VertexCode)
                    {
                        holes[holeIdx][j] = tc.Q;
                    }
                }
                ++holeIdx;
            }
        }
Ejemplo n.º 6
0
        ////////


        public static PointSet LoadDatPointSet(string filename, bool xflip, bool yflip, bool displayFlipX, bool displayFlipY, float rotateAngleInDegrees)
        {
            var points = new List <TriangulationPoint>();
            List <List <TriangulationPoint> > constrainedPoints = new List <List <TriangulationPoint> >();
            List <string>             constrainedPointSetNames  = new List <string>();
            List <TriangulationPoint> bounds      = new List <TriangulationPoint>();
            List <TriangulationPoint> currentList = points;
            double precision = TriangulationPoint.kVertexCodeDefaultPrecision;
            int    lineNum   = 0;
            bool   skipLine  = false;

            foreach (var line_ in File.ReadAllLines(filename))
            {
                ++lineNum;
                string line = line_.Trim();
                if (string.IsNullOrEmpty(line) ||
                    line.StartsWith("//") ||
                    line.StartsWith("#") ||
                    line.StartsWith(";"))
                {
                    continue;
                }
                if (!skipLine && line.StartsWith("/*"))
                {
                    skipLine = true;
                    continue;
                }
                else if (skipLine)
                {
                    if (line.StartsWith("*/"))
                    {
                        skipLine = false;
                    }
                    continue;
                }
                if (line.StartsWith("Precision", StringComparison.InvariantCultureIgnoreCase))
                {
                    if (line.Length > 9)
                    {
                        string precisionStr = line.Substring(9).Trim();
                        if (!double.TryParse(precisionStr, NumberStyles.Float, CultureInfo.InvariantCulture, out precision))
                        {
                            Console.WriteLine("Invalid Precision '" + precisionStr + "' in file " + filename + ", line " + lineNum.ToString() + ".  Setting to " + TriangulationPoint.kVertexCodeDefaultPrecision.ToString());
                            precision = TriangulationPoint.kVertexCodeDefaultPrecision;
                        }
                    }
                }
                else if (line.StartsWith("Set", StringComparison.InvariantCultureIgnoreCase))
                {
                    if (line.StartsWith("SetBegin"))
                    {
                        string[] setParts = line.Split(new[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
                        if (setParts.Length < 2)
                        {
                            continue;
                        }
                        //if (setParts[1].Equals("Constrained", StringComparison.InvariantCultureIgnoreCase))
                        if (setParts[1].Equals("Constrained", StringComparison.InvariantCultureIgnoreCase) ||
                            setParts[1].Equals("Unconstrained", StringComparison.InvariantCultureIgnoreCase))
                        {
                            currentList = new List <TriangulationPoint>();
                            constrainedPoints.Add(currentList);
                            if (setParts.Length > 2)
                            {
                                constrainedPointSetNames.Add(setParts[2]);
                            }
                            else
                            {
                                constrainedPointSetNames.Add("");
                            }
                        }
                        else if (bounds.Count == 0 && setParts[1].Equals("Bounds", StringComparison.InvariantCultureIgnoreCase))
                        {
                            currentList = bounds;
                        }
                        else
                        {
                            currentList = points;
                        }
                    }
                    else
                    {
                        currentList = points;
                    }
                }
                else
                {
                    var    xy = line.Split(new[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries);
                    double x, y;
                    if (xy != null &&
                        xy.Length >= 2 &&
                        double.TryParse(xy[0], NumberStyles.Float, CultureInfo.InvariantCulture, out x) &&
                        double.TryParse(xy[1], NumberStyles.Float, CultureInfo.InvariantCulture, out y))
                    {
                        currentList.Add(new PolygonPoint((xflip ? -1.0 : 1.0) * x, (yflip ? -1.0 : 1.0) * y));
                    }
                    else
                    {
                        Console.WriteLine("Invalid Input '" + line + "' in file " + filename + ", line " + lineNum.ToString());
                    }
                }
            }

            PointSet ps = null;

            if (constrainedPoints.Count > 0)
            {
                ConstrainedPointSet cps = null;
                if (bounds.Count < 3)
                {
                    points.AddRange(bounds);
                    cps = new ConstrainedPointSet(points);
                }
                else
                {
                    cps = new ConstrainedPointSet(bounds);
                    cps.AddRange(points);
                }
                int numConstrainedPointSets = constrainedPoints.Count;
                for (int i = 0; i < numConstrainedPointSets; ++i)
                {
                    List <TriangulationPoint> hole = constrainedPoints[i];
                    if (hole.Count < 3)
                    {
                        cps.AddRange(hole);
                    }
                    else
                    {
                        cps.AddHole(hole, constrainedPointSetNames[i]);
                    }
                }
                ps = cps;
            }
            else
            {
                if (bounds.Count < 3)
                {
                    points.AddRange(bounds);
                    ps = new PointSet(points);
                }
                else
                {
                    ps = new PointSet(bounds);
                    ps.AddRange(points);
                }
            }

            ps.FileName      = filename;
            ps.DisplayFlipX  = displayFlipX;
            ps.DisplayFlipY  = displayFlipY;
            ps.DisplayRotate = rotateAngleInDegrees;
            ps.Precision     = precision;

            return(ps);
        }