public void RemovePlan(IVolume plan) { Volume newVolume = plan as Volume; if (newVolume == null) { throw new NullReferenceException("Runtime Building Not Using Right Volume Type"); } _volumes.Remove(newVolume); List <IVolume> childPlans = new List <IVolume>(plan.AbovePlanList()); int childPlanCount = childPlans.Count; for (int cp = 0; cp < childPlanCount; cp++) { // childPlans--; // cp--; RemovePlan(plan.AbovePlanList()[cp]); } #if UNITY_EDITOR DestroyImmediate(plan.gameObject); #else Destroy(plan.gameObject); #endif MarkModified(); }
public void RemovePlan(IVolume plan) { VolumeRuntime newVolume = plan as VolumeRuntime; if (newVolume == null) { throw new NullReferenceException("Runtime Building Not Using Right Volume Type"); } _volumes.Remove(newVolume); List <IVolume> childPlans = new List <IVolume>(plan.AbovePlanList()); int childPlanCount = childPlans.Count; for (int cp = 0; cp < childPlanCount; cp++) { RemovePlan(plan.AbovePlanList()[cp]); } }
public List <IVolume> AllAboveVolumes(IVolume input) { List <IVolume> aboveVolumeList = new List <IVolume>(); List <IVolume> aboveVolumePprocessor = new List <IVolume>(input.AbovePlanList()); while (aboveVolumePprocessor.Count > 0) { if (aboveVolumePprocessor[0] != null) { aboveVolumeList.Add(aboveVolumePprocessor[0]); aboveVolumePprocessor.AddRange(aboveVolumePprocessor[0].AbovePlanList()); } aboveVolumePprocessor.RemoveAt(0); } return(aboveVolumeList); }
private void CheckPlanHeights() { int planCount = _volumes.Count; List <IVolume> modPlans = new List <IVolume>(); for (int p = 0; p < planCount; p++) { IVolume plan = _volumes[p]; if (plan.isModified) { modPlans.Add(plan); break; } } if (modPlans.Count == 0) { return; //nothing modified } IVolume modPlan = modPlans[0]; int linkPlans = modPlan.linkPlanCount; for (int pl = 0; pl < linkPlans; pl++) { IVolume linkedPlan = modPlan.LinkPlanList()[pl]; linkedPlan.floorHeight = modPlan.floorHeight; linkedPlan.floors = modPlan.floors; if (!modPlans.Contains(linkedPlan)) { modPlans.Add(linkedPlan); } } while (modPlans.Count > 0) { modPlan = modPlans[0]; modPlans.RemoveAt(0); int childPlans = modPlan.abovePlanCount; for (int cp = 0; cp < childPlans; cp++) { IVolume childPlan = modPlan.AbovePlanList()[cp]; childPlan.baseHeight = modPlan.planTotalHeight; modPlans.Add(childPlan); } } }
public static List <ParapetWallData> GetParapetShapes(IBuilding building, IVolume volume, Vector2[] points) { List <ParapetWallData> output = new List <ParapetWallData>(); int pointSize = points.Length; 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(); } for (int p = 0; p < pointSize; p++) { Vector2 p0 = points[p]; Vector2 p1 = p < pointSize - 1 ? points[p + 1] : points[0]; ParapetWallData data = new ParapetWallData(); data.index = p; data.type = ParapetWallData.Types.Full; data.pA = p0; data.pB = p1; for (int op = 0; op < numberOfAbovePlans; op++) { Vector2[] shape = aboveVolumeShapes[op]; bool p0Intr = PointInPolygon(p0, shape); bool p1Intr = PointInPolygon(p1, shape); if (p0Intr && p1Intr) { data.type = ParapetWallData.Types.None; break; //points within a shape } if (p0Intr || p1Intr) { int size = shape.Length; for (int s = 0; s < size; s++) { Vector2 px0 = shape[s]; int sb = s + 1; if (s == size - 1) { sb = 0; } Vector2 px1 = shape[sb]; if (PointOnLine(px0, p0, p1)) { data.Int = px0; data.type = p0Intr ? ParapetWallData.Types.IntersectiontoB : ParapetWallData.Types.AtoIntersection; break; } if (PointOnLine(px1, p0, p1)) { data.Int = px1; data.type = p0Intr ? ParapetWallData.Types.IntersectiontoB : ParapetWallData.Types.AtoIntersection; break; } if (FastLineIntersection(p0, p1, px0, px1)) { Vector2 ip = FindIntersection(p0, p1, px0, px1); data.Int = ip; data.type = p0Intr ? ParapetWallData.Types.IntersectiontoB : ParapetWallData.Types.AtoIntersection; break; } } } } output.Add(data); } 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); }
public static int MinimumFloor(IBuilding building, IVolume inPlan, int pointIndex) { int output = 0; int subjectActualBaseFloor = building.VolumeBaseFloor(inPlan); int subjectActualTopFloor = subjectActualBaseFloor + inPlan.floors; int pointIndexB = (pointIndex + 1) % inPlan.numberOfPoints; Vector2Int p0 = inPlan[pointIndex].position; Vector2Int p1 = inPlan[pointIndexB].position; List <IVolume> aboveVolumeList = building.AllAboveVolumes(inPlan); int volumeCount = building.numberOfVolumes; for (int f = 0; f < volumeCount; f++) { IVolume volume = building[f]; // if(inPlan == volume) continue; int actualBaseFloor = building.VolumeBaseFloor(volume); int actualTopFloor = actualBaseFloor + volume.floors; if (!(subjectActualBaseFloor < actualTopFloor && subjectActualTopFloor > actualBaseFloor)) { continue; //volumes don't affect each other } // if(volume.abovePlans.Contains(inPlan)) continue; if (aboveVolumeList.Contains(volume)) { continue; //this volume is connected above the subject and cannot effect a facade } if (inPlan.AbovePlanList().Contains(volume)) { continue; //this volume is connected above the subject and cannot effect a facade } if (building.AllAboveVolumes(volume).Contains(inPlan)) { continue; //this volume is connected below the subject and cannot effect } // if (building.AllAboveVolumes(inPlan).Contains(volume)) continue;//this volume is connected below the subject and cannot effect // if(inPlan.abovePlans.Contains(volume)) continue; int pointCount = volume.numberOfPoints; for (int p = 0; p < pointCount; p++) { if (volume == inPlan && p == pointIndex)//self connecting plans need to cut off facades { continue; } Vector2Int pB0 = volume[p].position; if (pB0 != p0 && pB0 != p1) { continue; } int pB = (p + 1) % volume.numberOfPoints; Vector2Int pB1 = volume[pB].position; if (pB1 != p0 && pB1 != p1) { continue; } if (output == 0) { output = volume.floors; } else { output = Mathf.Min(volume.floors, output); } } } return(output); }