public static VolumeShape[] GetBottomShape(IBuilding building, IVolume volume, Vector2[] usePoints = null) { VolumeShape[] output; Clipper clipper = new Clipper(); if (usePoints == null) { List <Vector2Int> newPoints = new List <Vector2Int>(); List <Vector2Int> wallAnchors = volume.wallAnchors; for (int w = 0; w < wallAnchors.Count; w++) { if (!newPoints.Contains(wallAnchors[w])) { newPoints.Add(wallAnchors[w]); } } usePoints = Vector2Int.Parse(newPoints.ToArray()); } Paths subj = new Paths(); // if (usePoints == null) // subj.Add(VolumeToPath(volume)); // else subj.Add(Vector2ToPath(usePoints)); Paths clip = new Paths(); IVolume[] belowVolumes = GetBelowVolumes(building, volume); int numberOfBelowVolumes = belowVolumes.Length; Vector2[][] belowVolumeShapes = new Vector2[numberOfBelowVolumes][]; for (int op = 0; op < numberOfBelowVolumes; op++) { belowVolumeShapes[op] = belowVolumes[op].AllPointsV2(); clip.Add(Vector2ToPath(belowVolumeShapes[op])); } if (clip.Count > 0) { PolyTree pTree = new PolyTree(); clipper.AddPaths(subj, PolyType.ptSubject, true); clipper.AddPaths(clip, PolyType.ptClip, true); clipper.Execute(ClipType.ctDifference, pTree); int shapeCount = pTree.ChildCount; output = new VolumeShape[shapeCount]; for (int s = 0; s < shapeCount; s++) { PolyNode node = pTree.Childs[s]; output[s] = new VolumeShape(); output[s].outer = PathToVector2(node.Contour); int holeCount = node.ChildCount; output[s].holes = new Vector2[holeCount][]; for (int h = 0; h < holeCount; h++) { PolyNode holeNode = node.Childs[h]; output[s].holes[h] = PathToVector2(holeNode.Contour); } } } else { output = new VolumeShape[1]; output[0] = new VolumeShape(); output[0].outer = PathToVector2(subj[0]); output[0].holes = new Vector2[0][]; } return(output); }
public static VolumeShape[] GetTopShape(IBuilding building, IVolume volume, Vector2[] usePoints = null) { VolumeShape[] output; Clipper clipper = new Clipper(); Paths subj = new Paths(); if (usePoints == null) { subj.Add(VolumeToPath(volume)); } else { subj.Add(Vector2ToPath(usePoints)); } Paths clip = new Paths(); int numberOfAbovePlans = volume.abovePlanCount; Vector2[][] aboveVolumeShapes = new Vector2[numberOfAbovePlans][]; for (int op = 0; op < numberOfAbovePlans; op++) { if (volume.AbovePlanList()[op] == null) { continue; } aboveVolumeShapes[op] = volume.AbovePlanList()[op].AllPointsV2(); clip.Add(Vector2ToPath(aboveVolumeShapes[op])); } VerticalOpening[] volumeOpenings = BuildrUtils.GetOpeningsQuick(building, volume); int numberOfOpenings = volumeOpenings.Length; int volumeTopFloor = volume.floors + building.VolumeBaseFloor(volume); for (int op = 0; op < numberOfOpenings; op++) { if (!volumeOpenings[op].FloorIsIncluded(volumeTopFloor)) { continue; } bool isInOtherVolume = false; Vector2[] openingPoints = volumeOpenings[op].Points(); int openingSize = openingPoints.Length; for (int v = 0; v < numberOfAbovePlans; v++) { if (volume.AbovePlanList()[v] == null) { continue; } for (int p = 0; p < openingSize; p++) { if (PointInPolygon(openingPoints[p], aboveVolumeShapes[v])) { isInOtherVolume = true; break; } } if (isInOtherVolume) { break; } } if (!isInOtherVolume) { clip.Add(OpeningToPath(volumeOpenings[op])); } } if (clip.Count > 0) { PolyTree pTree = new PolyTree(); clipper.AddPaths(subj, PolyType.ptSubject, true); clipper.AddPaths(clip, PolyType.ptClip, true); clipper.Execute(ClipType.ctDifference, pTree, PolyFillType.pftNonZero, PolyFillType.pftNonZero); int shapeCount = pTree.ChildCount; // Debug.Log("GetTopShape "+shapeCount); output = new VolumeShape[shapeCount]; for (int s = 0; s < shapeCount; s++) { PolyNode node = pTree.Childs[s]; output[s] = new VolumeShape(); output[s].outer = PathToVector2(node.Contour); int holeCount = node.ChildCount; output[s].holes = new Vector2[holeCount][]; for (int h = 0; h < holeCount; h++) { PolyNode holeNode = node.Childs[h]; output[s].holes[h] = PathToVector2(holeNode.Contour); } } } else { output = new VolumeShape[1]; output[0] = new VolumeShape(); output[0].outer = usePoints; output[0].holes = new Vector2[0][]; } SplitSelfIntersecting(output); return(output); }