/// <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(); }
/// <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; } } } }