예제 #1
0
        /***************************************************/

        public static bool IsEqual(this BHG.Line bhLine, RHG.LineCurve rhLine, double tolerance = BHG.Tolerance.Distance)
        {
            if (bhLine == null & rhLine == null)
            {
                return(true);
            }

            return(bhLine.IsEqual(rhLine.Line, tolerance));
        }
예제 #2
0
        /***************************************************/

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

            return(new RHG.Line(line.Start.ToRhino(), line.End.ToRhino()));
        }
예제 #3
0
        /***************************************************/

        private static Element ToRevitElement(this ModelInstance modelInstance, MEPCurveType mEPType, RevitSettings settings)
        {
            if (mEPType == null || modelInstance == null)
            {
                return(null);
            }

            if (!(modelInstance.Location is ICurve))
            {
                Compute.InvalidFamilyPlacementTypeError(modelInstance, mEPType);
                return(null);
            }

            Document document = mEPType.Document;

            BH.oM.Geometry.Line line = modelInstance.Location as BH.oM.Geometry.Line;

            Level level = document.LevelBelow(line, settings);

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

            Autodesk.Revit.DB.Line revitLine = line.ToRevit();
            if (revitLine == null)
            {
                return(null);
            }

            XYZ startPoint = revitLine.GetEndPoint(0);
            XYZ endPoint   = revitLine.GetEndPoint(1);

            if (mEPType is Autodesk.Revit.DB.Electrical.CableTrayType)
            {
                return(Autodesk.Revit.DB.Electrical.CableTray.Create(document, mEPType.Id, startPoint, endPoint, level.Id));
            }
            else if (mEPType is Autodesk.Revit.DB.Electrical.ConduitType)
            {
                return(Autodesk.Revit.DB.Electrical.Conduit.Create(document, mEPType.Id, startPoint, endPoint, level.Id));
            }
            else if (mEPType is Autodesk.Revit.DB.Plumbing.PipeType)
            {
                Autodesk.Revit.DB.Plumbing.PipingSystemType pst = new FilteredElementCollector(document).OfClass(typeof(Autodesk.Revit.DB.Plumbing.PipingSystemType)).OfType <Autodesk.Revit.DB.Plumbing.PipingSystemType>().FirstOrDefault();
                return(Autodesk.Revit.DB.Plumbing.Pipe.Create(document, pst.Id, mEPType.Id, level.Id, startPoint, endPoint));
            }
            else if (mEPType is Autodesk.Revit.DB.Mechanical.DuctType)
            {
                Autodesk.Revit.DB.Mechanical.MechanicalSystemType mst = new FilteredElementCollector(document).OfClass(typeof(Autodesk.Revit.DB.Mechanical.MechanicalSystemType)).OfType <Autodesk.Revit.DB.Mechanical.MechanicalSystemType>().FirstOrDefault();
                return(Autodesk.Revit.DB.Mechanical.Duct.Create(document, mst.Id, mEPType.Id, level.Id, startPoint, endPoint));
            }
            else
            {
                return(null);
            }
        }
예제 #4
0
        /***************************************************/

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

            return(bhLine.Start.IsEqual(rhLine.PointAt(0), tolerance) &&
                   bhLine.End.IsEqual(rhLine.PointAt(1), tolerance));
        }
예제 #5
0
        /***************************************************/

        public static BH.oM.Geometry.Line LocationCurveColumn(this FamilyInstance familyInstance, RevitSettings settings = null)
        {
            settings = settings.DefaultIfNull();

            BH.oM.Geometry.Line curve = null;

            if (familyInstance.IsSlantedColumn)
            {
                curve = (familyInstance.Location as LocationCurve).Curve.IFromRevit() as BH.oM.Geometry.Line;
            }
            else
            {
                Parameter baseLevelParam = familyInstance.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_PARAM);
                if (baseLevelParam != null)
                {
                    Parameter topLevelParam   = familyInstance.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_PARAM);
                    Parameter baseOffsetParam = familyInstance.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM);
                    Parameter topOffsetParam  = familyInstance.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM);

                    double baseLevel  = (familyInstance.Document.GetElement(baseLevelParam.AsElementId()) as Level).ProjectElevation;
                    double topLevel   = (familyInstance.Document.GetElement(topLevelParam.AsElementId()) as Level).ProjectElevation;
                    double baseOffset = baseOffsetParam.AsDouble();
                    double topOffset  = topOffsetParam.AsDouble();

                    XYZ loc      = (familyInstance.Location as LocationPoint).Point;
                    XYZ baseNode = new XYZ(loc.X, loc.Y, baseLevel + baseOffset);
                    XYZ topNode  = new XYZ(loc.X, loc.Y, topLevel + topOffset);
                    curve = new oM.Geometry.Line {
                        Start = baseNode.PointFromRevit(), End = topNode.PointFromRevit()
                    };
                }
            }

            if (curve != null)
            {
                Output <double, double> extensions = familyInstance.ColumnExtensions(settings);
                double startExtension = extensions.Item1;
                double endExtension   = extensions.Item2;

                if (Math.Abs(startExtension) > settings.DistanceTolerance || Math.Abs(endExtension) > settings.DistanceTolerance)
                {
                    Vector direction = curve.Direction();
                    curve = new oM.Geometry.Line {
                        Start = curve.Start - direction * startExtension, End = curve.End + direction * endExtension
                    };
                }
            }

            if (curve == null)
            {
                familyInstance.FramingCurveNotFoundWarning();
            }

            return(curve);
        }
예제 #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);
            }
        }
예제 #7
0
        internal static global::Topologic.Edge EdgeByLine(BH.oM.Geometry.Line bhomLine)
        {
            if (bhomLine.Infinite)
            {
                throw new ArgumentException("Infinite line is not supported.");
            }

            global::Topologic.Vertex startVertex = Create.VertexByPoint(bhomLine.Start);
            global::Topologic.Vertex endVertex   = Create.VertexByPoint(bhomLine.End);

            return(global::Topologic.Edge.ByStartVertexEndVertex(startVertex, endVertex));
        }
예제 #8
0
        public static SpeckleLine ToSpeckle(this BHG.Line l)
        {
            if (l == null)
            {
                return(default(SpeckleLine));
            }

            SpeckleLine speckleLine = new SpeckleLine(
                new double[] { l.Start.X, l.Start.Y, l.Start.Z, l.End.X, l.End.Y, l.End.Z }
                );

            return(speckleLine);
        }
예제 #9
0
        internal static BH.oM.Geometry.Line Line(global::Topologic.Edge edge)
        {
            global::Topologic.Vertex startVertex = edge.StartVertex;
            Point bhomStartPoint = Convert.Point(startVertex);

            global::Topologic.Vertex endVertex = edge.EndVertex;
            Point bhomEndPoint = Convert.Point(endVertex);

            BH.oM.Geometry.Line line = new BH.oM.Geometry.Line {
                Start = bhomStartPoint, End = bhomEndPoint, Infinite = false
            };
            return(line);
        }
예제 #10
0
        /***************************************************/

        public static ICurve LocationCurveFraming(this FamilyInstance familyInstance, RevitSettings settings = null)
        {
            settings = settings.DefaultIfNull();

            ICurve curve = (familyInstance.Location as LocationCurve)?.Curve?.IFromRevit();

            if (curve == null || (!(curve is NurbsCurve) && curve.ILength() <= settings.DistanceTolerance))
            {
                familyInstance.FramingCurveNotFoundWarning();
                return(null);
            }

            BH.oM.Geometry.Line line = curve as BH.oM.Geometry.Line;
            if (line == null)
            {
                familyInstance.NonLinearFramingOffsetWarning();
                return(curve);
            }

            Transform transform = familyInstance.GetTotalTransform();
            Vector    dir       = line.Direction();

            BH.oM.Geometry.Plane startPlane = new oM.Geometry.Plane {
                Origin = line.Start, Normal = dir
            };
            BH.oM.Geometry.Plane endPlane = new oM.Geometry.Plane {
                Origin = line.End, Normal = dir
            };
            BH.oM.Geometry.Line transformedLine = BH.Engine.Geometry.Create.Line(transform.Origin.PointFromRevit(), transform.BasisX.VectorFromRevit());
            line = new BH.oM.Geometry.Line {
                Start = transformedLine.PlaneIntersection(startPlane, true), End = transformedLine.PlaneIntersection(endPlane, true)
            };

            double startExtension = familyInstance.LookupParameterDouble(BuiltInParameter.START_EXTENSION);

            if (!double.IsNaN(startExtension))
            {
                line.Start = line.Start - dir * startExtension;
            }

            double endExtension = familyInstance.LookupParameterDouble(BuiltInParameter.END_EXTENSION);

            if (!double.IsNaN(endExtension))
            {
                line.End = line.End + dir * endExtension;
            }

            return(line);
        }
예제 #11
0
        internal static global::Topologic.Edge EdgeByCurve(ICurve bhomCurve)
        {
            // Currently only handle lines
            BH.oM.Geometry.Line bhomLine = bhomCurve as BH.oM.Geometry.Line;
            if (bhomLine != null)
            {
                return(EdgeByLine(bhomLine));
            }

            Arc bhomArc = bhomCurve as Arc;

            if (bhomArc != null)
            {
                return(EdgeByArc(bhomArc));
            }

            Circle bhomCircle = bhomCurve as Circle;

            if (bhomCircle != null)
            {
                return(EdgeByCircle(bhomCircle));
            }

            Ellipse bhomEllipse = bhomCurve as Ellipse;

            if (bhomEllipse != null)
            {
                return(EdgeByEllipse(bhomEllipse));
            }

            BH.oM.Geometry.NurbsCurve bhomNurbsCurve = bhomCurve as BH.oM.Geometry.NurbsCurve;
            if (bhomNurbsCurve != null)
            {
                return(EdgeByNurbsCurve(bhomNurbsCurve));
            }

            throw new NotImplementedException("This type of Curve is not supported.");
        }
예제 #12
0
        public static List <BH.oM.Geometry.Line> LocationCurveMEP(this MEPCurve mepCurve, out bool isStartConnected, out bool isEndConnected, RevitSettings settings = null)
        {
            settings = settings.DefaultIfNull();

            // Determine start and end points, which if the MEP linear object is connected to
            // a fitting then uses the fitting origin as either start/end
            List <BH.oM.Geometry.Point> allPoints = new List <BH.oM.Geometry.Point>();

            var tolerance = BH.oM.Adapters.Revit.Tolerance.Vertex.FromSI(UnitType.UT_Length);

            //add placeholder for extra lines required to snap multi-connected fittings
            BH.oM.Geometry.Line extraLine1 = null;
            BH.oM.Geometry.Line extraLine2 = null;

            //save points to recreate line later
            List <BH.oM.Geometry.Point> endPoints = new List <BH.oM.Geometry.Point>();
            List <BH.oM.Geometry.Point> midPoints = new List <BH.oM.Geometry.Point>();

            // Get connectors
            ConnectorManager connectorManager = mepCurve.ConnectorManager;
            ConnectorSet     connectorSet     = connectorManager.Connectors;
            List <Connector> c1Connectors     = connectorSet.Cast <Connector>().ToList();

            isStartConnected = false;
            isEndConnected   = false;

            // the following logic is applied below
            // we must get both END connectors of mepcurve SELF
            // for each END connector c1 check if it's connected
            // if connected check its references (every object that refers to it)
            // and grab c2 that is not from SELF (meaning the fitting connected to it)
            // grab c2 object owner, if it's a fitting then get all connectors
            // grab c3 from fitting 1 that is not c2 (retrieves the other end of fitting 1)
            // if c3 is connected then get its references
            // and grab c4 that is not c3
            // grab c4 object owner, if it's a fitting then get all connectors
            // grab c5 from fitting 2 that is not c4 (retrieves the other end of fitting 1)

            // depending on the conditions above it'll try to recreate the linear object
            // either by a simple straight line from connector to connector
            //     - MEP curve without fittings
            //     - or MEP curve that connects with/without fitting
            // or adds extra lines if MEP curve is connected by a chain (up to 2 devices) of fittings
            //     - if this is the case then it performs the aforementioned loop to find all possible connections
            // also any connectors that are not END in the beginning must be accounted
            //     - mid connectors means mep curves connected without fittings (in particular cable trays)

            for (int i = 0; i < c1Connectors.Count; i++)
            {
                BH.oM.Geometry.Point locationToSnap   = null;
                BH.oM.Geometry.Point locationFromSnap = null;

                Connector c1 = c1Connectors[i];
                if (c1.ConnectorType == ConnectorType.End)
                {
                    locationFromSnap = BH.Engine.Geometry.Modify.RoundCoordinates(Convert.PointFromRevit(c1.Origin), 4);
                    if (c1.IsConnected)
                    {
                        List <Connector> c2Connectors = (c1.AllRefs).Cast <Connector>().ToList();
                        for (int j = 0; j < c2Connectors.Count; j++)
                        {
                            Connector c2 = c2Connectors[j];
                            if (c2.Owner.Id != c1.Owner.Id)
                            {
                                if (!(c2.Owner is MEPCurve))
                                {
                                    FamilyInstance   familyInstance1   = c2.Owner as FamilyInstance;
                                    ConnectorManager connectorManager1 = familyInstance1.MEPModel.ConnectorManager;
                                    List <Connector> c3Connectors      = (connectorManager1.Connectors).Cast <Connector>().ToList();
                                    if (c3Connectors.Count == 2)
                                    {
                                        for (int k = 0; k < c3Connectors.Count; k++)
                                        {
                                            Connector c3 = c3Connectors[k];
                                            if (c3.Origin.DistanceTo(c1.Origin) > tolerance)
                                            {
                                                if (c3.IsConnected)
                                                {
                                                    List <Connector> c4Connectors = (c3.AllRefs).Cast <Connector>().ToList();
                                                    for (int l = 0; l < c4Connectors.Count; l++)
                                                    {
                                                        Connector c4 = c4Connectors[l];
                                                        if (c4.Owner.Id != c2.Owner.Id && c4.Owner.Id != c1.Owner.Id)
                                                        {
                                                            if (!(c4.Owner is MEPCurve))
                                                            {
                                                                FamilyInstance   familyInstance2   = c4.Owner as FamilyInstance;
                                                                ConnectorManager connectorManager2 = familyInstance2.MEPModel.ConnectorManager;
                                                                List <Connector> c5Connectors      = (connectorManager2.Connectors).Cast <Connector>().ToList();
                                                                if (c5Connectors.Count == 2)
                                                                {
                                                                    for (int m = 0; m < c5Connectors.Count; m++)
                                                                    {
                                                                        Connector c5 = c5Connectors[m];
                                                                        if (c5.Origin.DistanceTo(c4.Origin) > tolerance)
                                                                        {
                                                                            locationToSnap = BH.Engine.Geometry.Modify.RoundCoordinates(Convert.PointFromRevit(c5.Origin), 4);
                                                                            BH.oM.Geometry.Line longLine = BH.Engine.Geometry.Create.Line(locationToSnap, locationFromSnap);
                                                                            locationToSnap = BH.Engine.Geometry.Modify.RoundCoordinates(longLine.PointAtParameter(0.5), 4);

                                                                            endPoints.Add(BH.Engine.Geometry.Modify.RoundCoordinates(Convert.PointFromRevit(c1.Origin), 4));
                                                                            BH.oM.Geometry.Line shortLine = BH.Engine.Geometry.Create.Line(locationToSnap, locationFromSnap);

                                                                            if (c1.Id == 0)
                                                                            {
                                                                                extraLine1 = shortLine;
                                                                                if (c5.IsConnected)
                                                                                {
                                                                                    isStartConnected = true;
                                                                                }
                                                                            }
                                                                            else
                                                                            {
                                                                                extraLine2 = shortLine;
                                                                                if (c5.IsConnected)
                                                                                {
                                                                                    isEndConnected = true;
                                                                                }
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                                else
                                                                {
                                                                    //meaning this fitting could be a T or a cross shape
                                                                    locationToSnap = BH.Engine.Geometry.Modify.RoundCoordinates(Convert.FromRevit((familyInstance2.Location) as LocationPoint), 4);
                                                                    BH.oM.Geometry.Line shortLine = BH.Engine.Geometry.Create.Line(locationToSnap, locationFromSnap);
                                                                    endPoints.Add(BH.Engine.Geometry.Modify.RoundCoordinates(Convert.PointFromRevit(c1.Origin), 4));

                                                                    if (c1.Id == 0)
                                                                    {
                                                                        extraLine1 = shortLine;
                                                                        if (c5Connectors.Any(x => x.IsConnected == true))
                                                                        {
                                                                            isStartConnected = true;
                                                                        }
                                                                    }
                                                                    else
                                                                    {
                                                                        extraLine2 = shortLine;
                                                                        if (c5Connectors.Any(x => x.IsConnected == true))
                                                                        {
                                                                            isEndConnected = true;
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                            else
                                                            {
                                                                endPoints.Add(BH.Engine.Geometry.Modify.RoundCoordinates(Convert.FromRevit((c3.Owner.Location) as LocationPoint), 4));
                                                                if (c1.Id == 0)
                                                                {
                                                                    isStartConnected = true;
                                                                }
                                                                else
                                                                {
                                                                    isEndConnected = true;
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    endPoints.Add(BH.Engine.Geometry.Modify.RoundCoordinates(Convert.PointFromRevit(c1.Origin), 4));
                                                    locationToSnap = BH.Engine.Geometry.Modify.RoundCoordinates(Convert.PointFromRevit(c3.Origin), 4);
                                                    BH.oM.Geometry.Line shortLine = BH.Engine.Geometry.Create.Line(locationToSnap, locationFromSnap);

                                                    if (c1.Id == 0)
                                                    {
                                                        extraLine1 = shortLine;
                                                    }
                                                    else
                                                    {
                                                        extraLine2 = shortLine;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    else
                                    {
                                        //meaning fitting could be a T or a cross
                                        endPoints.Add(BH.Engine.Geometry.Modify.RoundCoordinates(Convert.FromRevit((familyInstance1.Location) as LocationPoint), 4));
                                        if (c1.Id == 0)
                                        {
                                            if (c3Connectors.Any(x => x.IsConnected == true))
                                            {
                                                isStartConnected = true;
                                            }
                                        }
                                        else
                                        {
                                            if (c3Connectors.Any(x => x.IsConnected == true))
                                            {
                                                isEndConnected = true;
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    endPoints.Add(BH.Engine.Geometry.Modify.RoundCoordinates(Convert.PointFromRevit(c1.Origin), 4));
                                    if (c1.Id == 0)
                                    {
                                        isStartConnected = true; // because c1 is connected
                                    }
                                    else
                                    {
                                        isEndConnected = true; //because c1 is connected
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        endPoints.Add(BH.Engine.Geometry.Modify.RoundCoordinates(Convert.PointFromRevit(c1.Origin), 4));
                    }
                }
                else
                {
                    //if MEP linear object has connections that don't take fitting,
                    //then we need to store the point to later split the curve
                    midPoints.Add(BH.Engine.Geometry.Modify.RoundCoordinates(Convert.PointFromRevit(c1.Origin), 4));
                }
            }

            //split MEP linear object if there was any other MEP linear object connected to it without fitting
            BH.oM.Geometry.Line        line   = BH.Engine.Geometry.Create.Line(endPoints[0], endPoints[1]);
            List <BH.oM.Geometry.Line> result = new List <BH.oM.Geometry.Line>();

            if (extraLine1 != null)
            {
                result.Add(extraLine1);
            }

            if (midPoints.Any())
            {
                result.AddRange(line.SplitAtPoints(midPoints));
            }
            else
            {
                result.Add(line);
            }

            if (extraLine2 != null)
            {
                result.Add(extraLine2);
            }

            return(MatchRevitOrder(result, mepCurve));
        }
예제 #13
0
        /***************************************************/

        public static void RenderMeshes(BHG.Line line, Rhino.Display.DisplayPipeline pipeline, DisplayMaterial material)
        {
            return;
        }
예제 #14
0
        /***************************************************/
        /****              Public methods               ****/
        /***************************************************/

        public static ICurve AdjustedLocationCurveFraming(this IFramingElement framingElement, FamilyInstance familyInstance, RevitSettings settings = null)
        {
            settings = settings.DefaultIfNull();

            ICurve curve = framingElement?.Location;

            if (curve == null || (!(curve is NurbsCurve) && curve.ILength() <= settings.DistanceTolerance))
            {
                framingElement.FramingCurveNotFoundWarning();
                return(null);
            }

            BH.oM.Geometry.Line line = curve as BH.oM.Geometry.Line;
            if (line == null)
            {
                familyInstance.NonLinearFramingOffsetWarning();
                return(curve);
            }

            Output <Vector, Vector> offsets = familyInstance.FramingOffsetVectors();
            Vector startOffset = -offsets.Item1;
            Vector endOffset   = -offsets.Item2;

            double startOffsetLength = startOffset.Length();
            double endOffsetLength   = endOffset.Length();

            if (startOffsetLength > settings.DistanceTolerance || endOffsetLength > settings.DistanceTolerance)
            {
                if ((startOffset - endOffset).Length() > settings.DistanceTolerance)
                {
                    BH.Engine.Reflection.Compute.RecordError(String.Format("Adjusted location curve of a Revit framing element could not be found because it has non-uniform offsets at ends. Revit ElementId: {0}", familyInstance.Id));
                    return(null);
                }

                Transform transform    = familyInstance.GetTotalTransform();
                Vector    yOffsetStart = new Vector {
                    X = transform.BasisY.X * startOffset.Y, Y = transform.BasisY.Y * startOffset.Y, Z = transform.BasisY.Z * startOffset.Y
                };
                Vector zOffsetStart = new Vector {
                    X = transform.BasisZ.X * startOffset.Z, Y = transform.BasisZ.Y * startOffset.Z, Z = transform.BasisZ.Z * startOffset.Z
                };
                Vector yOffsetEnd = new Vector {
                    X = transform.BasisY.X * endOffset.Y, Y = transform.BasisY.Y * endOffset.Y, Z = transform.BasisY.Z * endOffset.Y
                };
                Vector zOffsetEnd = new Vector {
                    X = transform.BasisZ.X * endOffset.Z, Y = transform.BasisZ.Y * endOffset.Z, Z = transform.BasisZ.Z * endOffset.Z
                };
                line = new BH.oM.Geometry.Line {
                    Start = line.Start.Translate(yOffsetStart + zOffsetStart), End = line.End.Translate(yOffsetEnd + zOffsetEnd)
                };
            }

            Vector dir            = line.Direction();
            double startExtension = familyInstance.LookupParameterDouble(BuiltInParameter.START_EXTENSION);

            if (!double.IsNaN(startExtension))
            {
                line.Start = line.Start + dir * startExtension;
            }

            double endExtension = familyInstance.LookupParameterDouble(BuiltInParameter.END_EXTENSION);

            if (!double.IsNaN(endExtension))
            {
                line.End = line.End - dir * endExtension;
            }

            return(line);
        }
예제 #15
0
        /***************************************************/

        public static bool SetLocation(this FamilyInstance element, IInstance instance, RevitSettings settings)
        {
            if (instance.Location == null)
            {
                return(false);
            }

            bool success = false;

            if (instance.Location is BH.oM.Geometry.Point)
            {
                LocationPoint location = element.Location as LocationPoint;
                if (location == null)
                {
                    return(false);
                }

                XYZ newLocation = ((BH.oM.Geometry.Point)instance.Location).ToRevit();

                if (location.Point.DistanceTo(newLocation) > settings.DistanceTolerance)
                {
                    if (element.Host != null)
                    {
                        if (element.HostFace == null)
                        {
                            List <Solid> hostSolids = element.Host.Solids(new Options());
                            if (hostSolids != null && hostSolids.All(x => !newLocation.IsInside(x, settings.DistanceTolerance)))
                            {
                                BH.Engine.Reflection.Compute.RecordWarning($"The new location point used to update the location of a family instance was outside of the host solid, the point has been snapped to the host. BHoM_Guid: {instance.BHoM_Guid} ElementId: {element.Id.IntegerValue}");
                            }
                        }
                        else
                        {
                            if (element.Host is ReferencePlane)
                            {
                                Autodesk.Revit.DB.Plane p = ((ReferencePlane)element.Host).GetPlane();
                                if (p.Origin.DistanceTo(newLocation) > settings.DistanceTolerance && Math.Abs((p.Origin - newLocation).Normalize().DotProduct(p.Normal)) > settings.AngleTolerance)
                                {
                                    BH.Engine.Reflection.Compute.RecordError($"Location update failed: the new location point used on update of a family instance does not lie in plane with its reference plane. BHoM_Guid: {instance.BHoM_Guid} ElementId: {element.Id.IntegerValue}");
                                    return(false);
                                }
                            }
                            else
                            {
                                Autodesk.Revit.DB.Face face = element.Host.GetGeometryObjectFromReference(element.HostFace) as Autodesk.Revit.DB.Face;

                                XYZ       toProject         = newLocation;
                                Transform instanceTransform = null;
                                if (element.Host is FamilyInstance && !((FamilyInstance)element.Host).HasModifiedGeometry())
                                {
                                    instanceTransform = ((FamilyInstance)element.Host).GetTotalTransform();
                                    toProject         = (instanceTransform.Inverse.OfPoint(newLocation));
                                }

                                IntersectionResult ir = face?.Project(toProject);
                                if (ir == null)
                                {
                                    BH.Engine.Reflection.Compute.RecordError($"Location update failed: the new location point used on update of a family instance could not be placed on its host face. BHoM_Guid: {instance.BHoM_Guid} ElementId: {element.Id.IntegerValue}");
                                    return(false);
                                }

                                newLocation = ir.XYZPoint;
                                if (instanceTransform != null)
                                {
                                    newLocation = (instanceTransform.OfPoint(newLocation));
                                }

                                if (ir.Distance > settings.DistanceTolerance)
                                {
                                    BH.Engine.Reflection.Compute.RecordWarning($"The location point used on update of a family instance has been snapped to its host face. BHoM_Guid: {instance.BHoM_Guid} ElementId: {element.Id.IntegerValue}");
                                }
                            }
                        }
                    }

                    location.Point = newLocation;
                    success        = true;
                }

                if (instance.Orientation?.X != null)
                {
                    Transform transform = element.GetTotalTransform();
                    XYZ       newX      = instance.Orientation.X.ToRevit().Normalize();
                    if (1 - Math.Abs(transform.BasisX.DotProduct(newX)) > settings.AngleTolerance)
                    {
                        XYZ          revitNormal;
                        XYZ          bHoMNormal;
                        FamilySymbol fs = element.Document.GetElement(element.GetTypeId()) as FamilySymbol;
                        if (fs != null && fs.Family.FamilyPlacementType == FamilyPlacementType.OneLevelBasedHosted)
                        {
                            revitNormal = transform.BasisY;
                            bHoMNormal  = instance.Orientation.Y.ToRevit().Normalize();
                        }
                        else
                        {
                            revitNormal = transform.BasisZ;
                            bHoMNormal  = instance.Orientation.Z.ToRevit().Normalize();
                        }

                        if (1 - Math.Abs(revitNormal.DotProduct(bHoMNormal)) > settings.AngleTolerance)
                        {
                            BH.Engine.Reflection.Compute.RecordWarning($"The orientation applied to the family instance on update has different normal than the original one. Only in-plane rotation has been applied, the orientation out of plane has been ignored. BHoM_Guid: {instance.BHoM_Guid} ElementId: {element.Id.IntegerValue}");
                        }

                        double angle = transform.BasisX.AngleOnPlaneTo(newX, revitNormal);
                        if (Math.Abs(angle) > settings.AngleTolerance)
                        {
                            ElementTransformUtils.RotateElement(element.Document, element.Id, Autodesk.Revit.DB.Line.CreateBound(newLocation, newLocation + transform.BasisZ), angle);
                            success = true;
                        }
                    }
                }
            }
            else if (instance.Location is ICurve && element.Host != null)
            {
                LocationCurve       location = element.Location as LocationCurve;
                BH.oM.Geometry.Line l        = instance.Location as BH.oM.Geometry.Line;
                if (location == null || l == null)
                {
                    return(false);
                }

                XYZ       start             = l.Start.ToRevit();
                XYZ       end               = l.End.ToRevit();
                Transform instanceTransform = null;
                if (element.Host is FamilyInstance && !((FamilyInstance)element.Host).HasModifiedGeometry())
                {
                    instanceTransform = ((FamilyInstance)element.Host).GetTotalTransform();
                    start             = (instanceTransform.Inverse.OfPoint(start));
                    end = (instanceTransform.Inverse.OfPoint(end));
                }

                Autodesk.Revit.DB.Face face = element.Host.GetGeometryObjectFromReference(element.HostFace) as Autodesk.Revit.DB.Face;
                IntersectionResult     ir1  = face?.Project(start);
                IntersectionResult     ir2  = face?.Project(end);
                if (ir1 == null || ir2 == null)
                {
                    BH.Engine.Reflection.Compute.RecordError($"Location update failed: the new location line used on update of a family instance could not be placed on its host face. BHoM_Guid: {instance.BHoM_Guid} ElementId: {element.Id.IntegerValue}");
                    return(false);
                }

                if (ir1.Distance > settings.DistanceTolerance || ir2.Distance > settings.DistanceTolerance)
                {
                    BH.Engine.Reflection.Compute.RecordWarning($"The location line used on update of a family instance has been snapped to its host face. BHoM_Guid: {instance.BHoM_Guid} ElementId: {element.Id.IntegerValue}");
                }

                start = ir1.XYZPoint;
                end   = ir2.XYZPoint;
                if (instanceTransform != null)
                {
                    start = instanceTransform.OfPoint(start);
                    end   = instanceTransform.OfPoint(end);
                }

                Autodesk.Revit.DB.Line newLocation = Autodesk.Revit.DB.Line.CreateBound(start, end);
                if (!newLocation.IsSimilar(location.Curve, settings))
                {
                    location.Curve = newLocation;
                    success        = true;
                }
            }
            else
            {
                success = SetLocation(element, instance.Location as dynamic, settings);
            }

            return(success);
        }
예제 #16
0
        public static global::Topologic.Topology TopologyByGeometry(BH.oM.Geometry.IGeometry geometry, double tolerance = 0.0001)
        {
            BH.oM.Geometry.Point bhomPoint = geometry as BH.oM.Geometry.Point;
            if (bhomPoint != null)
            {
                return(Create.VertexByPoint(bhomPoint));
            }

            // Handle polyline and polycurve first
            BH.oM.Geometry.Polyline bhomPolyline = geometry as BH.oM.Geometry.Polyline;
            if (bhomPolyline != null)
            {
                if (bhomPolyline.ControlPoints.Count < 2)
                {
                    throw new Exception("An invalid polyline with fewer than 2 control points is given.");
                }
                else if (bhomPolyline.ControlPoints.Count == 2)
                {
                    BH.oM.Geometry.Line bhomLine = BH.Engine.Geometry.Create.Line(bhomPolyline.ControlPoints[0], bhomPolyline.ControlPoints[1]);
                    return(Create.EdgeByLine(bhomLine));
                }
                else
                {
                    return(Create.WireByPolyLine(bhomPolyline));
                }
            }

            BH.oM.Geometry.PolyCurve bhomPolyCurve = geometry as BH.oM.Geometry.PolyCurve;
            if (bhomPolyCurve != null)
            {
                if (bhomPolyCurve.Curves.Count == 0)
                {
                    throw new Exception("An invalid polycurve with no curve is given.");
                }
                else if (bhomPolyCurve.Curves.Count == 1)
                {
                    BH.oM.Geometry.ICurve bhomACurve = bhomPolyCurve.Curves[0];
                    return(Create.EdgeByCurve(bhomACurve));
                }
                else
                {
                    return(Create.WireByPolyCurve(bhomPolyCurve));
                }
            }

            // Then curve
            BH.oM.Geometry.ICurve bhomCurve = geometry as BH.oM.Geometry.ICurve;
            if (bhomCurve != null)
            {
                return(Create.EdgeByCurve(bhomCurve));
            }

            // Do polysurface first.
            BH.oM.Geometry.PolySurface bhomPolySurface = geometry as BH.oM.Geometry.PolySurface;
            if (bhomPolySurface != null)
            {
                return(Create.ShellByPolySurface(bhomPolySurface, tolerance));
            }

            // Then surface
            BH.oM.Geometry.ISurface bhomSurface = geometry as BH.oM.Geometry.ISurface;
            if (bhomSurface != null)
            {
                return(Create.FaceBySurface(bhomSurface));
            }

            BH.oM.Geometry.ISolid bhomSolid = geometry as BH.oM.Geometry.ISolid;
            if (bhomSolid != null)
            {
                return(Create.CellBySolid(bhomSolid, tolerance));
            }

            BH.oM.Geometry.BoundingBox bhomBoundingBox = geometry as BH.oM.Geometry.BoundingBox;
            if (bhomBoundingBox != null)
            {
                return(Create.CellByBoundingBox(bhomBoundingBox));
            }

            BH.oM.Geometry.CompositeGeometry bhomCompositeGeometry = geometry as BH.oM.Geometry.CompositeGeometry;
            if (bhomCompositeGeometry != null)
            {
                return(Create.ClusterByCompositeGeometry(bhomCompositeGeometry, tolerance));
            }

            BH.oM.Geometry.Mesh bhomMesh = geometry as BH.oM.Geometry.Mesh;
            if (bhomMesh != null)
            {
                return(Create.TopologyByMesh(bhomMesh));
            }

            throw new NotImplementedException("This BHoM geometry is not yet supported.");
        }
예제 #17
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);
        }
예제 #18
0
        public static List <BH.oM.MEP.System.CableTray> CableTrayFromRevit(this Autodesk.Revit.DB.Electrical.CableTray revitCableTray, RevitSettings settings = null, Dictionary <string, List <IBHoMObject> > refObjects = null)
        {
            settings = settings.DefaultIfNull();

            // Reuse a BHoM cable tray from refObjects if it has been converted before
            List <BH.oM.MEP.System.CableTray> bhomCableTrays = refObjects.GetValues <BH.oM.MEP.System.CableTray>(revitCableTray.Id);

            if (bhomCableTrays != null)
            {
                return(bhomCableTrays);
            }
            else
            {
                bhomCableTrays = new List <BH.oM.MEP.System.CableTray>();
            }

            // Section properties
            BH.oM.MEP.System.SectionProperties.CableTraySectionProperty sectionProperty = BH.Revit.Engine.Core.Query.CableTraySectionProperty(revitCableTray, settings);

            // Orientation angle
            double orientationAngle = revitCableTray.OrientationAngle(settings);

            bool isStartConnected = false;
            bool isEndConnected   = false;
            List <BH.oM.Geometry.Line> queried = Query.LocationCurveMEP(revitCableTray, out isStartConnected, out isEndConnected, settings);

            Vector revitCableTrayVector = BH.Engine.Geometry.Modify.RoundCoordinates(VectorFromRevit((revitCableTray.Location as LocationCurve).Curve.GetEndPoint(0) - (revitCableTray.Location as LocationCurve).Curve.GetEndPoint(1)), 4).Normalise();

            for (int i = 0; i < queried.Count; i++)
            {
                BH.oM.Geometry.Line        segment     = queried[i];
                BH.oM.MEP.System.CableTray thisSegment = new CableTray
                {
                    StartPoint         = segment.StartPoint(),
                    EndPoint           = segment.EndPoint(),
                    SectionProperty    = sectionProperty,
                    ConnectionProperty = new CableTrayConnectionProperty(),
                    OrientationAngle   = orientationAngle
                };

                Vector bhomCableTrayVector = BH.Engine.Geometry.Modify.RoundCoordinates((thisSegment.StartPoint - thisSegment.EndPoint), 4).Normalise();

                if (queried.Count > 1)
                {
                    if (i == 0) //meaning it's the start segment of the revit cable tray that was split
                    {
                        if (BH.Engine.Geometry.Query.IsEqual(revitCableTrayVector, bhomCableTrayVector))
                        {
                            thisSegment.ConnectionProperty.IsStartConnected = isStartConnected;
                            thisSegment.ConnectionProperty.IsEndConnected   = true;
                        }
                        else
                        {
                            thisSegment.ConnectionProperty.IsStartConnected = true;
                            thisSegment.ConnectionProperty.IsEndConnected   = isStartConnected;
                        }
                    }
                    else if (i == queried.Count - 1) //meaning it's the end segment of the revit cable tray that was split
                    {
                        if (BH.Engine.Geometry.Query.IsEqual(revitCableTrayVector, bhomCableTrayVector))
                        {
                            thisSegment.ConnectionProperty.IsStartConnected = true;
                            thisSegment.ConnectionProperty.IsEndConnected   = isEndConnected;
                        }
                        else
                        {
                            thisSegment.ConnectionProperty.IsStartConnected = isEndConnected;
                            thisSegment.ConnectionProperty.IsEndConnected   = true;
                        }
                    }
                    else //meaning it's all mid segments of the revit cable tray that was split
                    {
                        thisSegment.ConnectionProperty.IsStartConnected = true;
                        thisSegment.ConnectionProperty.IsEndConnected   = true;
                    }
                }
                else
                {
                    if (BH.Engine.Geometry.Query.IsEqual(revitCableTrayVector, bhomCableTrayVector))
                    {
                        thisSegment.ConnectionProperty.IsStartConnected = isStartConnected;
                        thisSegment.ConnectionProperty.IsEndConnected   = isEndConnected;
                    }
                    else
                    {
                        thisSegment.ConnectionProperty.IsStartConnected = isEndConnected;
                        thisSegment.ConnectionProperty.IsEndConnected   = isStartConnected;
                    }
                }

                //Set identifiers, parameters & custom data
                thisSegment.SetIdentifiers(revitCableTray);
                thisSegment.CopyParameters(revitCableTray, settings.ParameterSettings);
                thisSegment.SetProperties(revitCableTray, settings.ParameterSettings);
                bhomCableTrays.Add(thisSegment);
            }

            refObjects.AddOrReplace(revitCableTray.Id, bhomCableTrays);
            return(bhomCableTrays);
        }
예제 #19
0
        /***************************************************/

        public static void RenderWires(BHG.Line line, Rhino.Display.DisplayPipeline pipeline, Color bhColour)
        {
            pipeline.DrawLine(line.ToRhino(), bhColour, 2);
        }