Пример #1
0
        static Surface FromExtrudedSurface(IList <DB.Curve> curves, DB.BoundingBoxUV bboxUV, double relativeTolerance)
        {
            var ctol = relativeTolerance * Revit.ShortCurveTolerance;

            var axis = new LineCurve
                       (
                new Line(curves[0].GetEndPoint(0).ToPoint3d(), curves[1].GetEndPoint(0).ToPoint3d()),
                0.0,
                1.0
                       );

            Curve curveU = ToRhino(curves[0]);

            curveU.Translate(axis.PointAt(bboxUV.Min.V) - curveU.PointAtStart);

            Curve curveV = new LineCurve(new Line(axis.PointAt(bboxUV.Min.V), axis.PointAt(bboxUV.Max.V)));

            if (ctol != 0.0)
            {
                curveU = curveU.Extend(CurveEnd.Both, ctol, CurveExtensionStyle.Smooth);
                curveV = curveV.Extend(CurveEnd.Both, ctol, CurveExtensionStyle.Smooth);
            }

            return(SumSurface.Create(curveU, curveV));
        }
Пример #2
0
        public bool lineWithinRegion(Brep region, LineCurve line)
        {
            //Check if line is completely within a planar region
            int agreement = 0;

            Point3d midPt = line.PointAt((line.Domain.Max - line.Domain.Min) / 2);

            foreach (BrepLoop loop in region.Loops)
            {
                if (loop.LoopType == BrepLoopType.Outer)
                {
                    Curve iLoop = loop.To3dCurve();

                    PointContainment ptcontain = iLoop.Contains(midPt);

                    if (ptcontain != PointContainment.Inside)
                    {
                        agreement += 1;
                    }
                }

                if (loop.LoopType == BrepLoopType.Inner)
                {
                    Curve iLoop = loop.To3dCurve();

                    PointContainment ptcontain = iLoop.Contains(midPt);

                    if (ptcontain != PointContainment.Outside)
                    {
                        agreement += 1;
                    }
                }

                if (loop.LoopType == BrepLoopType.Slit)
                {
                    break;
                }

                if (loop.LoopType == BrepLoopType.Unknown)
                {
                    break;
                }
            }

            if (agreement == 0)
            {
                bool inside = true;
                return(inside);
            }
            else
            {
                bool inside = false;
                return(inside);
            }
        }
Пример #3
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            Point3d M = Point3d.Origin;
            Point3d A = Point3d.Origin;
            Point3d B = Point3d.Origin;

            DA.GetData <Point3d>(0, ref M);
            DA.GetData <Point3d>(1, ref A);
            DA.GetData <Point3d>(2, ref B);

            LineCurve AB = new LineCurve(A, B);
            double    t;

            AB.ClosestPoint(M, out t);

            DA.SetData(0, Utils.ClosestPointOnLine(M, A, B));
            DA.SetData(1, AB.PointAt(t));
        }
Пример #4
0
        public static Elevation drawElevation(Curve baseCurve, List <List <Household> > houseHolds, List <Core> cores)
        {
            double storiesHeight = Consts.FloorHeight;
            double pilotiHeight  = Consts.PilotiHeight;

            double windowSide   = 300;
            double windowLow    = 300;
            double windowHeight = 2100;

            Curve groundCurve = new LineCurve(new Point3d(0, 0, 0), new Point3d(baseCurve.GetLength(), 0, 0));

            List <Curve> outlineCurve = new List <Curve>();
            List <Curve> windowDetail = new List <Curve>();
            List <Curve> banister     = new List <Curve>();
            List <Curve> core         = new List <Curve>();

            List <double> widthList = new List <double>();

            foreach (List <Household> i in houseHolds)
            {
                foreach (Household j in i)
                {
                    widthList.Add(j.YLengthA);
                }
            }

            List <double> uniqueWidthList = widthList.Distinct().ToList();

            uniqueWidthList.Sort();

            List <Brep>   tempElevationBase = new List <Brep>();
            List <Curve>  BalconyBase       = new List <Curve>();
            List <double> pilotiParameter   = new List <double>();
            List <Curve>  coreBase          = new List <Curve>();

            for (int h = 0; h < houseHolds.Count(); h++)
            {
                for (int i = 0; i < houseHolds[h].Count(); i++)
                {
                    Point3d start = houseHolds[h][i].Origin + houseHolds[h][i].XDirection * (-houseHolds[h][i].XLengthB);
                    Point3d end   = houseHolds[h][i].Origin + houseHolds[h][i].XDirection * (houseHolds[h][i].XLengthA - houseHolds[h][i].XLengthB);

                    double startDomain; double endDomain;

                    baseCurve.ClosestPoint(start, out startDomain);
                    baseCurve.ClosestPoint(end, out endDomain);

                    if (h == 0)
                    {
                        pilotiParameter.Add((endDomain - baseCurve.Domain.T0) * baseCurve.GetLength() + groundCurve.Domain.T0);
                        pilotiParameter.Add((startDomain - baseCurve.Domain.T0) * baseCurve.GetLength() + groundCurve.Domain.T0);
                    }

                    Curve tempHousingBase = new LineCurve(groundCurve.PointAt((startDomain - baseCurve.Domain.T0) * baseCurve.GetLength() + groundCurve.Domain.T0), groundCurve.PointAt((endDomain - baseCurve.Domain.T0) * baseCurve.GetLength() + groundCurve.Domain.T0));

                    tempHousingBase.Transform(Transform.Translation(new Vector3d(0, start.Z, 0)));
                    Curve tempHousingTop = tempHousingBase.DuplicateCurve();
                    tempHousingTop.Transform(Transform.Translation(new Vector3d(0, storiesHeight, 0)));

                    Curve[] tempLoftBase = { tempHousingBase, tempHousingTop };

                    Brep tempHousingBrep = Brep.CreateFromLoft(tempLoftBase, Point3d.Unset, Point3d.Unset, LoftType.Straight, false)[0];

                    Curve tempBalconyBase = tempHousingBase.DuplicateCurve();
                    tempBalconyBase.Transform(Transform.Translation(new Vector3d(0, windowLow, 0)));

                    double balconyBaseStart; double balconyBaseEnd;

                    tempBalconyBase.LengthParameter(windowSide, out balconyBaseStart);
                    tempBalconyBase.LengthParameter(tempBalconyBase.GetLength() - windowSide, out balconyBaseEnd);

                    tempBalconyBase = new LineCurve(tempBalconyBase.PointAt(balconyBaseStart), tempBalconyBase.PointAt(balconyBaseEnd));

                    tempElevationBase.Add(tempHousingBrep);
                    BalconyBase.Add(tempBalconyBase);
                }
            }

            for (int i = 0; i < cores.Count(); i++)
            {
                Point3d tempCoreStart = cores[i].Origin;
                Point3d tempCoreEnd   = cores[i].Origin + cores[i].XDirection * cores[i].Width;

                double startDomain; double endDomain;

                baseCurve.ClosestPoint(tempCoreStart, out startDomain);
                baseCurve.ClosestPoint(tempCoreEnd, out endDomain);

                Curve tempCoreBase = new LineCurve(groundCurve.PointAt((startDomain - baseCurve.Domain.T0) * baseCurve.GetLength() + groundCurve.Domain.T0), groundCurve.PointAt((endDomain - baseCurve.Domain.T0) * baseCurve.GetLength() + groundCurve.Domain.T0));

                coreBase.Add(tempCoreBase);
            }

            List <List <Brep> > elevationBrepSortedByWidth = new List <List <Brep> >();

            for (int i = 0; i < uniqueWidthList.Count(); i++)
            {
                elevationBrepSortedByWidth.Add(new List <Brep>());
            }

            for (int i = 0; i < widthList.Count; i++)
            {
                int tempWidthIndex = uniqueWidthList.IndexOf(widthList[i]);

                elevationBrepSortedByWidth[tempWidthIndex].Add(tempElevationBase[i]);
            }

            //elevationBrepSortedByWidth[elevationBrepSortedByWidth.Count() - 1].AddRange(DrawPiloti(groundCurve, pilotiParameter.Distinct().ToList(), pilotiHeight));

            List <Curve> joinedOutLineCurve = new List <Curve>();

            foreach (List <Brep> i in elevationBrepSortedByWidth)
            {
                Brep[] joinedBreps = Brep.JoinBreps(i, 2);

                foreach (Brep j in joinedBreps)
                {
                    outlineCurve.AddRange(j.DuplicateNakedEdgeCurves(true, true).ToList());
                    joinedOutLineCurve.AddRange(Curve.JoinCurves(j.DuplicateNakedEdgeCurves(true, true).ToList()).ToList());
                }
            }

            for (int i = 0; i < coreBase.Count(); i++)
            {
                Curve coreBoundary = offsetOneSide(coreBase[i], (cores[i].Stories + 1) * Consts.FloorHeight + Consts.PilotiHeight);

                core.AddRange(getOuterCurve(coreBoundary, joinedOutLineCurve));
            }

            foreach (Curve h in BalconyBase)
            {
                double[]      target            = { double.MaxValue, 2, 2 };
                List <object> typeList          = new List <object>();
                List <Curve>  splittedBaseCurve = divideBaseCurve(h, target, out typeList);

                for (int i = 0; i < splittedBaseCurve.Count(); i++)
                {
                    List <string> windowTypeList = Enum.GetValues(typeof(WindowType)).Cast <WindowType>().Select(v => v.ToString()).ToList();

                    if (windowTypeList.IndexOf(typeList[i].ToString()) != -1)
                    {
                        int index = windowTypeList.IndexOf(typeList[i].ToString());

                        List <Curve> tempWindow = drawWindow((WindowType)index, splittedBaseCurve[i], windowHeight);

                        windowDetail.AddRange(tempWindow);

                        List <Curve> tempBanister = drawBanister(splittedBaseCurve[i], 25, 900);

                        banister.AddRange(tempBanister);
                    }
                }
            }

            return(new Elevation(outlineCurve, windowDetail, banister, core));
        }
Пример #5
0
        public static Section drawSection(List <Curve> baseCurve, List <List <List <Household> > > households, List <List <Core> > cores, Plot plot)
        {
            double storyHeight   = 2800;
            double floorLow      = 200;
            double wallThickness = 200;

            List <int> index = new List <int>();

            Curve perpCurve = new LineCurve(Point3d.Origin, Point3d.Origin);

            List <Curve>        Boundary = new List <Curve>();
            List <Curve>        Room     = new List <Curve>();
            List <Curve>        Core     = new List <Curve>();
            List <RoomNamecard> roomName = new List <RoomNamecard>();

            List <Curve> JoinedBoundaryCrv = new List <Curve>();
            List <Curve> CoreBase          = new List <Curve>();

            List <double> uniqueParameter = getUniqueParameter(baseCurve, plot, out perpCurve, out index);

            Curve groundCurve = new LineCurve(Point3d.Origin, new Point3d(perpCurve.GetLength(), 0, 0));

            for (int i = 0; i < index.Count(); i++)
            {
                Core tempCoreProperty = cores[index[i]][0];

                Point3d tempCoreStart = tempCoreProperty.Origin;
                Point3d tempCoreEnd   = tempCoreProperty.Origin + tempCoreProperty.YDirection * tempCoreProperty.Depth;

                double tempStartParam; double tempEndParam;

                perpCurve.ClosestPoint(tempCoreStart, out tempStartParam);
                perpCurve.ClosestPoint(tempCoreEnd, out tempEndParam);

                Curve tempCoreBase = new LineCurve(groundCurve.PointAt(tempStartParam), groundCurve.PointAt(tempEndParam));

                CoreBase.Add(offsetOneSide(tempCoreBase, Consts.PilotiHeight + Consts.FloorHeight * (tempCoreProperty.Stories + 1)));
            }


            for (int i = 0; i < uniqueParameter.Count(); i++)
            {
                List <Brep> boundary           = new List <Brep>();
                int         tempIntersectIndex = 0;

                for (int j = 0; j < households[i].Count(); j++)
                {
                    Household tempHousehold    = households[i][j][tempIntersectIndex];
                    double    widthAsParameter = tempHousehold.YLengthA * (groundCurve.Domain.T1 - groundCurve.Domain.T0) / groundCurve.GetLength();

                    Point3d tempStart = groundCurve.PointAt(uniqueParameter[i] - widthAsParameter / 2);
                    Point3d tempEnd   = groundCurve.PointAt(uniqueParameter[i] + widthAsParameter / 2);

                    Curve tempBase = new LineCurve(tempStart, tempEnd);
                    tempBase.Transform(Transform.Translation(new Vector3d(0, tempHousehold.Origin.Z, 0)));

                    Curve tempLoftBase = tempBase.DuplicateCurve();
                    tempLoftBase.Transform(Transform.Translation(new Vector3d(0, storyHeight, 0)));

                    Curve[] tempLoftBaseSet = { tempBase, tempLoftBase };
                    Brep    tempLoftedBrep  = Brep.CreateFromLoft(tempLoftBaseSet, Point3d.Unset, Point3d.Unset, LoftType.Straight, false)[0];
                    boundary.Add(tempLoftedBrep);

                    Curve roomBase = tempBase.DuplicateCurve();
                    roomBase.Transform(Transform.Translation(new Vector3d(0, floorLow, 0)));

                    double tempRoombaseStart; double tempRoombaseEnd;

                    roomBase.LengthParameter(wallThickness, out tempRoombaseStart);
                    roomBase.LengthParameter(roomBase.GetLength() - wallThickness, out tempRoombaseEnd);

                    roomBase = new LineCurve(roomBase.PointAt(tempRoombaseStart), roomBase.PointAt(tempRoombaseEnd));

                    Curve room = offsetOneSide(roomBase, storyHeight - floorLow * 2);

                    RoomNamecard tempNamecard = RoomNamecard.CreateRoomNamecard(roomBase.PointAt(roomBase.Domain.Mid) + new Point3d(0, (storyHeight - floorLow * 2) / 2, 0), tempHousehold.GetArea(), storyHeight - floorLow * 2);

                    Room.Add(room);
                    roomName.Add(tempNamecard);
                }

                Brep[] joinedBoundary = Brep.JoinBreps(boundary, 0.1);

                foreach (Brep j in joinedBoundary)
                {
                    Curve[] tempNakedEdge = j.DuplicateNakedEdgeCurves(true, true);

                    Boundary.AddRange(tempNakedEdge.ToList());

                    JoinedBoundaryCrv.AddRange(Curve.JoinCurves(tempNakedEdge).ToList());
                }
            }

            List <Surroundinginfo> surrounding = checkSurrounding(perpCurve, plot, groundCurve);

            return(new Section(Boundary, Room, Core, surrounding, roomName));
        }
Пример #6
0
        private static List <double> getUniqueParameter(List <Curve> baseCurve, Plot plot, out Curve perpendicularCurve, out List <int> indexOfTheParameter)
        {
            List <double> output = new List <double>();

            //////////////////////////////////////////

            BoundingBox boundaryBox  = plot.Boundary.GetBoundingBox(false);
            double      extendLength = boundaryBox.Corner(true, true, true).DistanceTo(boundaryBox.Corner(false, false, true));

            Curve    tempCurve             = baseCurve[(int)(baseCurve.Count() / 2)];
            Point3d  centerPoint           = tempCurve.PointAt(tempCurve.Domain.Mid);
            Vector3d centerPointPerpVector = tempCurve.TangentAt(tempCurve.Domain.Mid);

            centerPointPerpVector.Transform(Transform.Rotation(Math.PI / 2, Point3d.Origin));
            perpendicularCurve = new LineCurve(centerPoint, centerPoint + centerPointPerpVector);

            double perpCurveStart = -extendLength; double perpCurveEnd = extendLength;

            perpendicularCurve = new LineCurve(perpendicularCurve.PointAt(perpCurveStart), perpendicularCurve.PointAt(perpCurveEnd));

            List <Point3d> pointOnPerpCurve = new List <Point3d>();

            foreach (Curve i in baseCurve)
            {
                double tempParameter;
                perpendicularCurve.ClosestPoint(i.PointAt(i.Domain.Mid), out tempParameter);

                pointOnPerpCurve.Add(perpendicularCurve.PointAt(tempParameter));
            }

            List <Point3d> uniquePointOnPerpCurve = Point3d.CullDuplicates(pointOnPerpCurve, 1000).ToList();
            List <double>  uniquePointParameter   = new List <double>();

            foreach (Point3d i in uniquePointOnPerpCurve)
            {
                double tempParameter;
                perpendicularCurve.ClosestPoint(i, out tempParameter);

                uniquePointParameter.Add(tempParameter);
            }

            RhinoList <Point3d> rhinoUniquePointOnPerpCurve = new RhinoList <Point3d>(uniquePointOnPerpCurve);

            rhinoUniquePointOnPerpCurve.Sort(uniquePointParameter.ToArray());
            uniquePointParameter.Sort();

            List <int> tempIndexOfParameter = new List <int>();

            foreach (Point3d i in rhinoUniquePointOnPerpCurve)
            {
                int index = pointOnPerpCurve.IndexOf(i);

                tempIndexOfParameter.Add(index);
            }

            ///

            indexOfTheParameter = tempIndexOfParameter;

            return(uniquePointParameter);
        }
Пример #7
0
        private Curve fromNorthRegulation(Apartment agOut, int stories)
        {
            Plot       plot       = agOut.Plot;
            Regulation regulation = new Regulation(stories);
            Polyline   temp;

            plot.Boundary.TryGetPolyline(out temp);
            Curve[] plotArr = temp.GetSegments().Select(n => n.ToNurbsCurve()).ToArray();

            //법규적용(일조에 의한 높이제한)

            double[] distanceFromNorth = new double[plotArr.Length];
            for (int i = 0; i < plotArr.Length; i++)
            {
                Vector3d tempVector = new Vector3d(plotArr[i].PointAt(plotArr[i].Domain.T1) - plotArr[i].PointAt(plotArr[i].Domain.T0));
                tempVector = tempVector / tempVector.Length;

                double moveDistance = 0;

                if (tempVector.X > 0 && plot.SimplifiedSurroundings[i] >= 0)
                {
                    double tempSineFactor = System.Math.Abs(tempVector.X);

                    double tempDistanceByRoad = plot.SimplifiedSurroundings[i] * 1000 / 2 * tempVector.Length / System.Math.Abs(tempVector.X);
                    if (tempDistanceByRoad < regulation.DistanceFromNorth)
                    {
                        moveDistance = regulation.DistanceFromNorth - tempDistanceByRoad;
                    }
                }

                distanceFromNorth[i] = moveDistance;
            }

            List <Point3d> distanceFromNorthPts = new List <Point3d>();

            for (int i = 0; i < plotArr.Length; i++)
            {
                int h = (i - 1 + plotArr.Length) % plotArr.Length;
                int j = (i + 1 + plotArr.Length) % plotArr.Length;

                double distH = distanceFromNorth[h];
                double distI = distanceFromNorth[i];
                double distJ = distanceFromNorth[j];

                if (distI == 0)
                {
                    distanceFromNorthPts.Add(plotArr[i].PointAt(plotArr[i].Domain.T0));
                    distanceFromNorthPts.Add(plotArr[i].PointAt(plotArr[i].Domain.T1));
                }
                else
                {
                    Curve tempCurve = new LineCurve(plotArr[i].PointAt(plotArr[i].Domain.T0), plotArr[i].PointAt(plotArr[i].Domain.T1));
                    tempCurve.Transform(Transform.Translation(new Vector3d(0, -distI, 0)));

                    var tempIntersect1 = Rhino.Geometry.Intersect.Intersection.CurveCurve(tempCurve, plotArr[h], 0, 0);
                    var tempIntersect2 = Rhino.Geometry.Intersect.Intersection.CurveCurve(tempCurve, plotArr[j], 0, 0);

                    if (tempIntersect1.Count > 0)
                    {
                        distanceFromNorthPts.Add(tempIntersect1[0].PointA);
                    }
                    else if (tempIntersect1.Count <= 0)
                    {
                        distanceFromNorthPts.Add(tempCurve.PointAt(tempCurve.Domain.T0));
                    }

                    if (tempIntersect2.Count > 0)
                    {
                        distanceFromNorthPts.Add(tempIntersect2[0].PointA);
                    }
                    else if (tempIntersect2.Count <= 0)
                    {
                        distanceFromNorthPts.Add(tempCurve.PointAt(tempCurve.Domain.T1));
                    }
                }
            }

            distanceFromNorthPts.Add(distanceFromNorthPts[0]);

            Curve fromNorthCurve = (new Polyline(distanceFromNorthPts)).ToNurbsCurve();

            return(fromNorthCurve);
        }
Пример #8
0
        public static void Make3d(string schemeName)
        {
            string inputLayerPath  = schemeName + "::EJLT Shapes";
            string outputLayerPath = schemeName + "::Walls";
            string doorsLayerPath  = schemeName + "::Doors";

            List <int>       layerIndexs;
            List <Curve>     curves   = LayerHelper.GetCurvesFromChild(inputLayerPath, out layerIndexs);
            List <Curve>     doors    = LayerHelper.GetCurvesFrom(doorsLayerPath);
            List <LineCurve> afterCut = new List <LineCurve>();

            List <Line> exploded = new List <Line>();

            foreach (Curve c in curves)
            {
                Polyline poly;
                c.TryGetPolyline(out poly);

                exploded.AddRange(poly.GetSegments());
            }

            List <Line> lineSegDoor = new List <Line>();
            List <List <LineCurve> > doorsPerSeg = new List <List <LineCurve> >();

            foreach (Line lineSeg in exploded)
            {
                List <LineCurve> doorsThisSeg = new List <LineCurve>();
                foreach (Curve door in doors)
                {
                    CurveIntersections inter = Intersection.CurveLine(door, lineSeg, Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance, 0.0);
                    if (inter.Count == 2)
                    {
                        LineCurve l1;

                        Point3d p1 = inter.First().PointA;
                        Point3d p2 = inter[1].PointA;
                        l1 = new LineCurve(p1, p2);
                        doorsThisSeg.Add(l1);
                    }
                }
                if (doorsThisSeg.Count > 0)
                {
                    lineSegDoor.Add(lineSeg);
                    doorsPerSeg.Add(doorsThisSeg);
                }
                else
                {
                    // no intersection, add to after cut
                    afterCut.Add(new LineCurve(lineSeg));
                }
            }

            for (int i = 0; i < lineSegDoor.Count; i++)
            {
                // points from all intersection points
                List <Point3d> intersectionPts = new List <Point3d>();
                intersectionPts.Add(lineSegDoor[i].From);
                intersectionPts.Add(lineSegDoor[i].To);
                foreach (LineCurve doorLine in doorsPerSeg[i])
                {
                    intersectionPts.Add(doorLine.PointAtStart);
                    intersectionPts.Add(doorLine.PointAtEnd);
                }
                List <Point3d> sortedPoints = intersectionPts.OrderBy(pnt => pnt.Y).ThenBy(pnt => pnt.X).ToList();

                // construct line segments
                for (int pi = 0; pi < sortedPoints.Count; pi = pi + 2)
                {
                    LineCurve cuttedSegment = new LineCurve(sortedPoints[pi], sortedPoints[pi + 1]);
                    bool      indoor        = false;
                    foreach (Curve door in doors)
                    {
                        if (door.Contains(cuttedSegment.PointAt(0.5), Plane.WorldXY, Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance) == PointContainment.Inside)
                        {
                            indoor = true;
                            break;
                        }
                    }
                    if (!indoor)
                    {
                        afterCut.Add(cuttedSegment);
                    }
                }
            }
            UnitSystem currentDocUnits  = RhinoDoc.ActiveDoc.ModelUnitSystem;
            double     unitSystemScaler = RhinoMath.UnitScale(UnitSystem.Feet, currentDocUnits);

            foreach (LineCurve wallLine in afterCut)
            {
                LayerHelper.BakeObjectToLayer(Extrusion.Create(wallLine, 8 * unitSystemScaler, false).ToBrep(), "Walls", schemeName);
            }
            Rhino.RhinoDoc.ActiveDoc.Views.Redraw();
        }
Пример #9
0
        //채광방향
        public static List <Curve> Lighting(Curve roadCenter, Plot plot, double aptAngle)
        {
            double d = 0;

            if (plot.PlotType != PlotTypes.상업지역)
            {
                if (plot.LegalMaxF <= 7)
                {
                    d = 0.25;
                }
                else
                {
                    d = 0.5;
                }
            }
            else
            {
                d = 0.25;
            }

            Curve basecurve = null;
            var   cp        = AreaMassProperties.Compute(plot.Boundary).Centroid;
            var   basev     = Vector3d.XAxis;

            basev.Rotate(aptAngle, Vector3d.ZAxis);
            var bounding = plot.Boundary.GetBoundingBox(false);

            basecurve = new LineCurve(cp - basev * bounding.Diagonal.Length / 2, cp + basev * bounding.Diagonal.Length / 2);

            List <Curve> result  = new List <Curve>();
            Curve        last    = roadCenter.DuplicateCurve();
            double       pheight = 3.3;
            double       fheight = 2.8;
            int          floor   = plot.LegalMaxF;

            List <Curve> debug = new List <Curve>();

            for (int i = 0; i < floor; i++)
            {
                var height   = pheight + fheight * i;
                var distance = d * (height - pheight);

                var segments = roadCenter.DuplicateSegments();
                for (int j = 0; j < segments.Length; j++)
                {
                    var ps = segments[j].PointAtStart;
                    var pe = segments[j].PointAtEnd;

                    double ds = 0;
                    double de = 0;


                    basecurve.ClosestPoint(ps, out ds);
                    basecurve.ClosestPoint(pe, out de);

                    Vector3d vs = basecurve.PointAt(ds) - ps;
                    Vector3d ve = basecurve.PointAt(de) - pe;
                    vs.Unitize();
                    ve.Unitize();

                    var mp = segments[j].PointAtNormalizedLength(0.5);
                    var ts = mp + vs;
                    var te = mp + ve;

                    if (roadCenter.Contains(ts) == PointContainment.Inside)
                    {
                        segments[j].Translate(vs * distance);
                    }
                    else if (roadCenter.Contains(te) == PointContainment.Inside)
                    {
                        segments[j].Translate(ve * distance);
                    }

                    segments[j].Translate(Vector3d.ZAxis * height);
                }

                List <Point3d> topoly = new List <Point3d>();
                for (int k = 0; k < segments.Length; k++)
                {
                    int    j  = (k + 1) % segments.Length;
                    Line   li = new Line(segments[k].PointAtStart, segments[k].PointAtEnd);
                    Line   lj = new Line(segments[j].PointAtStart, segments[j].PointAtEnd);
                    double paramA;
                    double paramB;
                    var    intersect = Rhino.Geometry.Intersect.Intersection.LineLine(li, lj, out paramA, out paramB, 0, false);

                    topoly.Add(li.PointAt(paramA));
                }

                topoly.Add(topoly[0]);
                var tempcurve        = new PolylineCurve(topoly);
                var rotation         = tempcurve.ClosedCurveOrientation(Vector3d.ZAxis);
                var selfintersection = Rhino.Geometry.Intersect.Intersection.CurveSelf(tempcurve, 0);

                var parameters = selfintersection.Select(n => n.ParameterA).ToList();

                parameters.AddRange(selfintersection.Select(n => n.ParameterB));

                var spl = tempcurve.Split(parameters);

                var f = NewJoin(spl);


                var merged = f.Where(n => n.ClosedCurveOrientation(Vector3d.ZAxis) == rotation).ToList();
                debug.AddRange(merged);


                for (int j = merged.Count - 1; j >= 0; j--)
                {
                    var tc = merged[j].DuplicateCurve();
                    tc.Translate(Vector3d.ZAxis * -tc.PointAtStart.Z);

                    if (Curve.CreateBooleanDifference(tc, last).Length == 0)
                    {
                        last = tc;
                        result.Add(merged[j]);
                    }
                }
            }

            return(result);
        }