public static bool NormalTowardsSpace(this BHG.Polyline pline, BHE.Space space)
        {
            BHG.Point centrePt = pline.Centre();

            List <BHG.Point> pts = BH.Engine.Geometry.Query.DiscontinuityPoints(pline);

            BHG.Plane plane = BH.Engine.Geometry.Create.Plane(pts[0], pts[1], pts[2]);

            //The polyline can be locally concave. Check if the polyline is clockwise.
            if (!BH.Engine.Geometry.Query.IsClockwise(pline, plane.Normal))
            {
                plane.Normal = -plane.Normal;
            }

            //Move centrepoint along the normal. If inside - flip the panel
            if (IsContaining(space, centrePt.Translate(plane.Normal)))
            {
                return(true);
            }
            else
            {
                return(false);
            }

            /***************************************************/
        }
Beispiel #2
0
        /***************************************************/

        private static bool TryAddSurface(this BRepBuilder brep, PlanarSurface ps)
        {
            try
            {
                BH.oM.Geometry.Plane    p  = ps.ExternalBoundary.IFitPlane();
                Autodesk.Revit.DB.Plane rp = p.ToRevit();

                BRepBuilderSurfaceGeometry bbsg = BRepBuilderSurfaceGeometry.Create(rp, null);
                BRepBuilderGeometryId      face = brep.AddFace(bbsg, false);

                brep.AddLoop(face, rp.Normal, ps.ExternalBoundary, true);

                foreach (ICurve c in ps.InternalBoundaries)
                {
                    brep.AddLoop(face, rp.Normal, c, false);
                }

                brep.FinishFace(face);
            }
            catch
            {
                BH.Engine.Reflection.Compute.RecordError("An attempt to create a planar surface failed.");
                return(false);
            }

            return(true);
        }
        /***************************************************/

        public static void RenderWires(BHG.Plane plane, Rhino.Display.DisplayPipeline pipeline, Color bhColour)
        {
            pipeline.DrawConstructionPlane(new Rhino.DocObjects.ConstructionPlane()
            {
                Plane = (plane.ToRhino()), ThickLineColor = bhColour, ThinLineColor = Color.Black, GridLineCount = 10
            });
        }
Beispiel #4
0
        /***************************************************/

        public static RHG.Plane ToRhino(this BHG.Plane plane)
        {
            if (plane == null)
            {
                return(default(RHG.Plane));
            }

            return(new RHG.Plane(plane.Origin.ToRhino(), plane.Normal.ToRhino()));
        }
Beispiel #5
0
        /***************************************************/
        /**** Public Methods  - Vectors                 ****/
        /***************************************************/

        public static bool IsEqual(this BHG.Plane bhPlane, RHG.Plane rhPlane, double tolerance = BHG.Tolerance.Distance)
        {
            if (bhPlane == null & rhPlane == default(RHG.Plane))
            {
                return(true);
            }

            return(bhPlane.Origin.IsEqual(rhPlane.Origin, tolerance) &&
                   bhPlane.Normal.IsEqual(rhPlane.Normal, tolerance));
        }
Beispiel #6
0
        /***************************************************/

        public static bool NormalAwayFromSpace(this BHG.Polyline pline, List <BHE.BuildingElement> elementsAsSpace)
        {
            List <BHG.Point> centrePtList = new List <BHG.Point>();

            BHG.Point centrePt = pline.Centre();
            centrePtList.Add(centrePt);

            if (!pline.IsClosed())
            {
                return(false);                   //Prevent failures of the clockwise check
            }
            List <BHG.Point> pts = BH.Engine.Geometry.Query.DiscontinuityPoints(pline);

            if (pts.Count < 3)
            {
                return(false);               //Protection in case there aren't enough points to make a plane
            }
            BHG.Plane plane = BH.Engine.Geometry.Create.Plane(pts[0], pts[1], pts[2]);



            //The polyline can be locally concave. Check if the polyline is clockwise.
            if (!BH.Engine.Geometry.Query.IsClockwise(pline, plane.Normal))
            {
                plane.Normal = -plane.Normal;
            }

            if (!BH.Engine.Geometry.Query.IsContaining(pline, centrePtList, false))
            {
                BHG.Point  pointOnLine = BH.Engine.Geometry.Query.ClosestPoint(pline, centrePt);
                BHG.Vector vector      = new BHG.Vector();
                if (BH.Engine.Geometry.Query.Distance(pointOnLine, centrePt) > BH.oM.Geometry.Tolerance.MicroDistance)
                {
                    vector = pointOnLine - centrePt;
                }
                else
                {
                    BHG.Line line = BH.Engine.Geometry.Query.GetLineSegment(pline, pointOnLine);
                    vector = ((line.Start - line.End).Normalise()).CrossProduct(plane.Normal);
                }

                centrePt = BH.Engine.Geometry.Modify.Translate(pointOnLine, BH.Engine.Geometry.Modify.Normalise(vector) * 0.001);
            }

            //Move centrepoint along the normal.
            if (BH.Engine.Environment.Query.IsContaining(elementsAsSpace, centrePt.Translate(plane.Normal * 0.01)))
            {
                return(false);
            }
            else
            {
                return(true);
            }
        }
Beispiel #7
0
        /***************************************************/
        /**** Public Methods                            ****/
        /***************************************************/

        public static double Orientation(IBuildingObject buildingPanel)
        {
            Panel panel = buildingPanel as Panel;

            BHG.Polyline pLine = new BHG.Polyline {
                ControlPoints = panel.PanelCurve.IControlPoints()
            };

            List <BHG.Point> pts = pLine.DiscontinuityPoints();

            BHG.Plane plane = BH.Engine.Geometry.Create.Plane(pts[0], pts[1], pts[2]); //Some protection on this needed maybe?

            BHG.Vector xyNormal = BH.Engine.Geometry.Create.Vector(0, 1, 0);

            return(BH.Engine.Geometry.Query.Angle(plane.Normal, xyNormal) * (180 / Math.PI));
        }
Beispiel #8
0
        /***************************************************/

        public static double Azimuth(this BHG.Polyline pline, BHG.Vector refVector)
        {
            double azimuth;

            List <BHG.Point> pts = BH.Engine.Geometry.Query.DiscontinuityPoints(pline);

            if (pts.Count < 3 || !BH.Engine.Geometry.Query.IsClosed(pline))
            {
                return(-1);                                                            //Protection in case there aren't enough points to make a plane
            }
            BHG.Plane plane = BH.Engine.Geometry.Create.Plane(pts[0], pts[1], pts[2]);

            //The polyline can be locally concave. Check if the polyline is clockwise.
            if (!BH.Engine.Geometry.Query.IsClockwise(pline, plane.Normal))
            {
                plane.Normal = -plane.Normal;
            }

            if (Geometry.Modify.Normalise(plane.Normal).Z == 1)
            {
                azimuth = 0;
            }
            else if (Geometry.Modify.Normalise(plane.Normal).Z == -1)
            {
                azimuth = 180;
            }
            else
            {
                BHG.Vector v1 = Geometry.Modify.Project(plane.Normal, BHG.Plane.XY);
                BHG.Vector v2 = (Geometry.Modify.Project(refVector, BHG.Plane.XY));

                azimuth = (BH.Engine.Geometry.Query.SignedAngle(v1, v2, BHG.Vector.ZAxis) * (180 / Math.PI));
                if (azimuth < 0)
                {
                    azimuth = 360 + azimuth;
                }
            }
            return(azimuth);
        }
Beispiel #9
0
        /***************************************************/

        public static double Tilt(this BHG.Polyline pline)
        {
            double tilt;

            List <BHG.Point> pts = BH.Engine.Geometry.Query.DiscontinuityPoints(pline);

            if (pts.Count < 3 || !BH.Engine.Geometry.Query.IsClosed(pline))
            {
                return(-1);                                                            //Error protection on pts having less than 3 elements to create a plane or pLine not being closed
            }
            BHG.Plane plane = BH.Engine.Geometry.Create.Plane(pts[0], pts[1], pts[2]);

            //The polyline can be locally concave. Check if the polyline is clockwise.
            if (!BH.Engine.Geometry.Query.IsClockwise(pline, plane.Normal))
            {
                plane.Normal = -plane.Normal;
            }

            tilt = BH.Engine.Geometry.Query.Angle(plane.Normal, BHG.Plane.XY.Normal) * (180 / Math.PI);

            return(tilt);
        }
Beispiel #10
0
        /***************************************************/
        /****               Public Methods              ****/
        /***************************************************/

        public static Element ToCurveElement(this ModelInstance modelInstance, Document document, RevitSettings settings = null, Dictionary <Guid, List <int> > refObjects = null)
        {
            CurveElement curveElement = refObjects.GetValue <CurveElement>(document, modelInstance.BHoM_Guid);

            if (curveElement != null)
            {
                return(curveElement);
            }

            settings = settings.DefaultIfNull();

            ICurve curve = modelInstance.Location as ICurve;

            if (curve == null)
            {
                return(null);
            }

            if (!curve.IIsPlanar(settings.DistanceTolerance))
            {
                modelInstance.NonPlanarCurveError();
                return(null);
            }

            Curve revitCurve = curve.IToRevit();

            if (revitCurve == null)
            {
                return(null);
            }

            if ((revitCurve is NurbSpline || revitCurve is HermiteSpline) && curve.IIsClosed(settings.DistanceTolerance))
            {
                modelInstance.ClosedNurbsCurveError();
                return(null);
            }

            Autodesk.Revit.DB.Plane revitPlane;
            BH.oM.Geometry.Plane    plane = curve.IFitPlane();
            if (plane == null)
            {
                revitPlane = revitCurve.ArbitraryPlane();
            }
            else
            {
                revitPlane = plane.ToRevit();
            }

            SketchPlane sketchPlane = SketchPlane.Create(document, revitPlane);

            curveElement = document.Create.NewModelCurve(revitCurve, sketchPlane);

            if (modelInstance.Properties != null)
            {
                string name = modelInstance.Properties.Name;
                if (!string.IsNullOrEmpty(name))
                {
                    Element element = new FilteredElementCollector(document).OfClass(typeof(GraphicsStyle)).ToList().Find(x => x.Name == name);
                    if (element != null)
                    {
                        curveElement.LineStyle = element;
                    }
                }
            }

            refObjects.AddOrReplace(modelInstance, curveElement);
            return(curveElement);
        }
        /***************************************************/

        public static void RenderMeshes(BHG.Plane plane, Rhino.Display.DisplayPipeline pipeline, DisplayMaterial material)
        {
            return;
        }
Beispiel #12
0
        public static List <Slice> CreateSlices(Group <Curve> edges, Vector direction, double increment = 0.001)
        {
            List <Slice> slices = new List <Slice>();

            List <double> cutAt         = new List <double>();
            List <double> sliceSegments = new List <double>();
            Plane         p             = new BH.oM.Geometry.Plane(Point.Origin, direction);

            for (int i = 0; i < edges.Count; i++)
            {
                for (int j = 0; j < edges[i].PointCount; j++)
                {
                    cutAt.Add(ArrayUtils.DotProduct(edges[i].ControlPoint(j), p.Normal));
                }
            }

            cutAt.Sort();
            cutAt = cutAt.Distinct <double>().ToList();


            double currentValue = ArrayUtils.DotProduct(edges.Bounds().Min, p.Normal);
            double max          = ArrayUtils.DotProduct(edges.Bounds().Max, p.Normal);
            int    index        = 0;

            while (currentValue < max)
            {
                if (cutAt.Count > index && currentValue > cutAt[index])
                {
                    sliceSegments.Add(cutAt[index]);
                    index++;
                }
                else
                {
                    sliceSegments.Add(currentValue);
                    currentValue += increment;
                }
            }

            sliceSegments.Add(max);


            for (int i = 0; i < sliceSegments.Count - 1; i++)
            {
                if (sliceSegments[i] == sliceSegments[i + 1])
                {
                    continue;
                }

                currentValue = (sliceSegments[i] + sliceSegments[i + 1]) / 2;

                //for (int edgeIndex = 0; edgeIndex < m_Edges.Count; edgeIndex++)
                //{
                //    if (edgeIndex == 3)
                //    {

                //    }
                //    y.AddRange(Intersect.PlaneCurve(new Plane(new Point(p.Normal * currentValue), p.Normal), m_Edges[edgeIndex], 0.00001));
                //}

                //List<double> isolatedCoords = new List<double>();

                //for (int point = 0; point < y.Count; point++)
                //{
                //    if (p.Normal.X > 0)
                //    {
                //        isolatedCoords.Add(y[point].Y);
                //    }
                //    else
                //    {
                //        isolatedCoords.Add(y[point].X);
                //    }
                //}


                //isolatedCoords.Sort();

                //if (isolatedCoords.Count % 2 != 0)
                //{
                //    for (int k = 0; k < isolatedCoords.Count - 1; k++)
                //    {
                //        if (isolatedCoords[k] == isolatedCoords[k + 1])
                //        {
                //            isolatedCoords.RemoveAt(k + 1);
                //        }
                //    }
                //}

                //for (int j = 0; j < isolatedCoords.Count - 1; j += 2)
                //{
                //    length = length + isolatedCoords[j + 1] - isolatedCoords[j];
                //}

                slices.Add(GetSliceAt(edges, currentValue, -sliceSegments[i] + sliceSegments[i + 1], p));
                //new Slice(-sliceSegments[i] + sliceSegments[i + 1], length, currentValue, isolatedCoords.ToArray()));
            }
            return(slices);
        }
Beispiel #13
0
        /***************************************************/
        /****              Public methods               ****/
        /***************************************************/

        public static Floor ToRevitFloor(this oM.Physical.Elements.Floor floor, Document document, RevitSettings settings = null, Dictionary <Guid, List <int> > refObjects = null)
        {
            if (floor == null || floor.Construction == null || document == null)
            {
                return(null);
            }

            Floor revitFloor = refObjects.GetValue <Floor>(document, floor.BHoM_Guid);

            if (revitFloor != null)
            {
                return(revitFloor);
            }

            PlanarSurface planarSurface = floor.Location as PlanarSurface;

            if (planarSurface == null)
            {
                return(null);
            }

            settings = settings.DefaultIfNull();

            FloorType floorType = floor.Construction?.ToRevitElementType(document, new List <BuiltInCategory> {
                BuiltInCategory.OST_Floors
            }, settings, refObjects) as FloorType;

            if (floorType == null)
            {
                floorType = floor.ElementType(document, settings);
            }

            if (floorType == null)
            {
                Compute.ElementTypeNotFoundWarning(floor);
                return(null);
            }

            double bottomElevation = floor.Location.IBounds().Min.Z;
            Level  level           = document.LevelBelow(bottomElevation.FromSI(UnitType.UT_Length), settings);

            oM.Geometry.Plane sketchPlane = new oM.Geometry.Plane {
                Origin = new BH.oM.Geometry.Point {
                    Z = bottomElevation
                }, Normal = Vector.ZAxis
            };
            ICurve     curve      = planarSurface.ExternalBoundary.IProject(sketchPlane);
            CurveArray curveArray = Create.CurveArray(curve.IToRevitCurves());

            BH.oM.Geometry.Plane slabPlane = planarSurface.FitPlane();
            if (1 - Math.Abs(Vector.ZAxis.DotProduct(slabPlane.Normal)) <= settings.AngleTolerance)
            {
                revitFloor = document.Create.NewFloor(curveArray, floorType, level, true);
            }
            else
            {
                Vector normal = slabPlane.Normal;
                if (normal.Z < 0)
                {
                    normal = -slabPlane.Normal;
                }

                double angle = normal.Angle(Vector.ZAxis);
                double tan   = Math.Tan(angle);

                XYZ dir = normal.Project(oM.Geometry.Plane.XY).ToRevit().Normalize();
                BH.oM.Geometry.Line ln = slabPlane.PlaneIntersection(sketchPlane);
                XYZ start = ln.ClosestPoint(curveArray.get_Item(0).GetEndPoint(0).PointFromRevit(), true).ToRevit();
                Autodesk.Revit.DB.Line line = Autodesk.Revit.DB.Line.CreateBound(start, start + dir);

                revitFloor = document.Create.NewSlab(curveArray, level, line, -tan, true);
                revitFloor.SetParameter(BuiltInParameter.ELEM_TYPE_PARAM, floorType.Id);
            }

            revitFloor.CheckIfNullPush(floor);
            if (revitFloor == null)
            {
                return(null);
            }

            document.Regenerate();

            if (planarSurface.InternalBoundaries != null)
            {
                foreach (ICurve hole in planarSurface.InternalBoundaries)
                {
                    document.Create.NewOpening(revitFloor, Create.CurveArray(hole.IProject(slabPlane).IToRevitCurves()), true);
                }
            }

            foreach (BH.oM.Physical.Elements.IOpening opening in floor.Openings)
            {
                PlanarSurface openingLocation = opening.Location as PlanarSurface;
                if (openingLocation == null)
                {
                    BH.Engine.Reflection.Compute.RecordWarning(String.Format("Conversion of a floor opening to Revit failed because its location is not a planar surface. Floor BHoM_Guid: {0}, Opening BHoM_Guid: {1}", floor.BHoM_Guid, opening.BHoM_Guid));
                    continue;
                }

                document.Create.NewOpening(revitFloor, Create.CurveArray(openingLocation.ExternalBoundary.IToRevitCurves()), true);

                if (!(opening is BH.oM.Physical.Elements.Void))
                {
                    BH.Engine.Reflection.Compute.RecordWarning(String.Format("Revit allows only void openings in floors, therefore the BHoM opening of type {0} has been converted to a void opening. Floor BHoM_Guid: {1}, Opening BHoM_Guid: {2}", opening.GetType().Name, floor.BHoM_Guid, opening.BHoM_Guid));
                }
            }

            double offset = revitFloor.LookupParameterDouble(BuiltInParameter.FLOOR_HEIGHTABOVELEVEL_PARAM);

            // Copy parameters from BHoM object to Revit element
            revitFloor.CopyParameters(floor, settings);

            // Update the offset in case the level had been overwritten.
            if (revitFloor.LevelId.IntegerValue != level.Id.IntegerValue)
            {
                Level newLevel = document.GetElement(revitFloor.LevelId) as Level;
                offset += (level.ProjectElevation - newLevel.ProjectElevation).ToSI(UnitType.UT_Length);
            }

            revitFloor.SetParameter(BuiltInParameter.FLOOR_HEIGHTABOVELEVEL_PARAM, offset);

            refObjects.AddOrReplace(floor, revitFloor);
            return(revitFloor);
        }