예제 #1
0
        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();
        }
예제 #2
0
        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]);
            }
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
                }
            }
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }