Пример #1
0
        /// <summary>
        /// Cuts the out front polygon.
        /// </summary>
        /// <param name="polyPoints">The poly points.</param>
        /// <param name="vwiwc">The Vertical Index Classification.</param>
        /// <param name="points">The points.</param>
        private static void CutOutFrontPolygon(List <Vector3DIndexClassification> polyPoints, Vector3DIndexClassification vwiwc, List <Vector3D> points)
        {
            points.Clear();

            var curVW = vwiwc;

            while (true)
            {
                curVW.AlreadyCuttedFront = true;
                points.Add(curVW.Vector);

                var curVWPair = polyPoints[curVW.CuttingFrontPairIndex];

                if (curVW.CuttingFrontPoint)
                {
                    if (!curVWPair.AlreadyCuttedFront)
                    {
                        curVW = curVWPair;
                    }
                    else
                    {
                        var curVWPrev = polyPoints[BspTreeBuilder.GetNext(curVW.Index - 1, polyPoints.Count)];
                        var curVWNext = polyPoints[BspTreeBuilder.GetNext(curVW.Index + 1, polyPoints.Count)];

                        if ((curVWPrev.Result == ClassifyPointResult.OnFront) && !curVWPrev.AlreadyCuttedFront)
                        {
                            curVW = curVWPrev;
                        }
                        else
                        if ((curVWNext.Result == ClassifyPointResult.OnFront) && !curVWNext.AlreadyCuttedFront)
                        {
                            curVW = curVWNext;
                        }
                        else
                        {
                            return;
                        }
                    }
                }
                else
                {
                    var curPrev = polyPoints[BspTreeBuilder.GetNext(curVW.Index - 1, polyPoints.Count)];
                    var curNext = polyPoints[BspTreeBuilder.GetNext(curVW.Index + 1, polyPoints.Count)];

                    if ((curPrev.Result != ClassifyPointResult.OnBack) && !curPrev.AlreadyCuttedFront)
                    {
                        curVW = curPrev;
                    }
                    else
                    if ((curNext.Result != ClassifyPointResult.OnBack) && !curNext.AlreadyCuttedFront)
                    {
                        curVW = curNext;
                    }
                    else
                    {
                        return;
                    }
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Split the polygon.
        /// </summary>
        /// <param name="poly">The Polygon</param>
        /// <param name="part">The Part</param>
        /// <param name="backPoly">The Back Polygon</param>
        /// <param name="frontPoly">The Front Polygon</param>
        private static void SplitPolygon(Polygon3D poly, Polygon3D part, out Polygon3D[] backPoly, out Polygon3D[] frontPoly)
        {
            var backP  = new List <Polygon3D>();
            var frontP = new List <Polygon3D>();

            // this code looks for points which lie on the part plane and divide polygon into two parts
            if (poly.Points != null)
            {
                var polyPoints      = new List <Vector3DIndexClassification>();
                var backPartPoints  = new List <Vector3DIndexClassification>();
                var frontPartPoints = new List <Vector3DIndexClassification>();

                var outpts = new List <Vector3D>();
                var inpts  = new List <Vector3D>();

                var count = poly.Points.Length;
                for (var i = 0; i < count; i++)
                {
                    var ptB   = poly.Points[i];
                    var ptC   = poly.Points[BspTreeBuilder.GetNext(i + 1, count)];
                    var sideB = ClassifyPoint(ptB, part);
                    var sideC = ClassifyPoint(ptC, part);

                    var vwiwcB = new Vector3DIndexClassification(ptB, polyPoints.Count, sideB);
                    polyPoints.Add(vwiwcB);

                    if ((sideB != sideC) && (sideB != ClassifyPointResult.OnPlane) &&
                        (sideC != ClassifyPointResult.OnPlane))
                    {
                        var v   = ptB - ptC;
                        var dir = part.Normal * (-part.D) - ptC;

                        var sv    = dir & part.Normal;
                        var sect  = sv / (part.Normal & v);
                        var ptP   = ptC + v * sect;
                        var vwiwc = new Vector3DIndexClassification(
                            ptP,
                            polyPoints.Count,
                            ClassifyPointResult.OnPlane);

                        polyPoints.Add(vwiwc);
                        backPartPoints.Add(vwiwc);
                        frontPartPoints.Add(vwiwc);
                    }
                    else
                    if (sideB == ClassifyPointResult.OnPlane)
                    {
                        var ptA   = poly.Points[BspTreeBuilder.GetNext(i - 1, count)];
                        var sideA = ClassifyPoint(ptA, part);
                        if ((sideA == sideC))
                        {
                            continue;
                        }

                        if ((sideA != ClassifyPointResult.OnPlane) && (sideC != ClassifyPointResult.OnPlane))
                        {
                            backPartPoints.Add(vwiwcB);
                            frontPartPoints.Add(vwiwcB);
                        }
                        else
                        if (sideA == ClassifyPointResult.OnPlane)
                        {
                            switch (sideC)
                            {
                            case ClassifyPointResult.OnBack:
                                backPartPoints.Add(vwiwcB);
                                break;

                            case ClassifyPointResult.OnFront:
                                frontPartPoints.Add(vwiwcB);
                                break;
                            }
                        }
                        else
                        if (sideC == ClassifyPointResult.OnPlane)
                        {
                            switch (sideA)
                            {
                            case ClassifyPointResult.OnBack:
                                backPartPoints.Add(vwiwcB);
                                break;

                            case ClassifyPointResult.OnFront:
                                frontPartPoints.Add(vwiwcB);
                                break;
                            }
                        }
                    }
                }

                if ((frontPartPoints.Count != 0) || (backPartPoints.Count != 0))
                {
                    for (var i = 0; i < backPartPoints.Count - 1; i += 2)
                    {
                        var vwiwc1 = backPartPoints[i];
                        var vwiwc2 = backPartPoints[i + 1];
                        vwiwc1.CuttingBackPoint     = true;
                        vwiwc2.CuttingBackPoint     = true;
                        vwiwc1.CuttingBackPairIndex = vwiwc2.Index;
                        vwiwc2.CuttingBackPairIndex = vwiwc1.Index;
                    }

                    for (var i = 0; i < frontPartPoints.Count - 1; i += 2)
                    {
                        var vwiwc1 = frontPartPoints[i];
                        var vwiwc2 = frontPartPoints[i + 1];
                        vwiwc1.CuttingFrontPoint     = true;
                        vwiwc2.CuttingFrontPoint     = true;
                        vwiwc1.CuttingFrontPairIndex = vwiwc2.Index;
                        vwiwc2.CuttingFrontPairIndex = vwiwc1.Index;
                    }

                    for (var i = 0; i < backPartPoints.Count - 1; i++)
                    {
                        var vwiwc = backPartPoints[i];
                        if (vwiwc.AlreadyCuttedBack)
                        {
                            continue;
                        }

                        BspTreeBuilder.CutOutBackPolygon(polyPoints, vwiwc, outpts);

                        if (outpts.Count > 2)
                        {
                            var points  = outpts.ToArray();
                            var polygon = new Polygon3D(points, poly);
                            polygon.CalcNormal(points[0], points[1], points[2]);
                            polygon.CalcNormal();
                            backP.Add(polygon);
                        }
                    }

                    for (var i = 0; i < frontPartPoints.Count - 1; i++)
                    {
                        var vwiwc = frontPartPoints[i];
                        if (vwiwc.AlreadyCuttedFront)
                        {
                            continue;
                        }

                        BspTreeBuilder.CutOutFrontPolygon(polyPoints, vwiwc, inpts);
                        if (inpts.Count > 2)
                        {
                            var points  = inpts.ToArray();
                            var polygon = new Polygon3D(points, poly);
                            polygon.CalcNormal(points[0], points[1], points[2]);
                            polygon.CalcNormal();
                            frontP.Add(polygon);
                        }
                    }
                }
            }
            else
            {
                backP.Add(poly);
                frontP.Add(poly);
            }

            backPoly  = backP.ToArray();
            frontPoly = frontP.ToArray();
        }