/***************************************************/ 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)); }
/***************************************************/ 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())); }
/***************************************************/ 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); } }
/***************************************************/ 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)); }
/***************************************************/ 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); }
/***************************************************/ 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); } }
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)); }
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); }
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); }
/***************************************************/ 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); }
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."); }
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)); }
/***************************************************/ public static void RenderMeshes(BHG.Line line, Rhino.Display.DisplayPipeline pipeline, DisplayMaterial material) { return; }
/***************************************************/ /**** 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); }
/***************************************************/ 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); }
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."); }
/***************************************************/ /**** 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); }
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); }
/***************************************************/ public static void RenderWires(BHG.Line line, Rhino.Display.DisplayPipeline pipeline, Color bhColour) { pipeline.DrawLine(line.ToRhino(), bhColour, 2); }