public static bool NormalTowardsSpace(this BHG.Polyline pline, BHE.Space space) { BHG.Point centrePt = pline.Centre(); List <BHG.Point> pts = BH.Engine.Geometry.Query.DiscontinuityPoints(pline); BHG.Plane plane = BH.Engine.Geometry.Create.Plane(pts[0], pts[1], pts[2]); //The polyline can be locally concave. Check if the polyline is clockwise. if (!BH.Engine.Geometry.Query.IsClockwise(pline, plane.Normal)) { plane.Normal = -plane.Normal; } //Move centrepoint along the normal. If inside - flip the panel if (IsContaining(space, centrePt.Translate(plane.Normal))) { return(true); } else { return(false); } /***************************************************/ }
/***************************************************/ public static BHG.Cylinder FromRhino(this RHG.Cylinder cylinder) { BHG.Point centre = cylinder.Center.FromRhino() + cylinder.Axis.FromRhino() * cylinder.Height1; return(new BHG.Cylinder { Centre = centre, Axis = cylinder.Axis.FromRhino(), Height = cylinder.TotalHeight, Radius = cylinder.CircleAt(0.0).Radius }); }
public static RHG.NurbsCurve ToRhino5(this BHG.NurbsCurve bCurve) { if (bCurve == null) { return(null); } List <double> knots = bCurve.Knots; List <double> weights = bCurve.Weights; List <BHG.Point> ctrlPts = bCurve.ControlPoints; RHG.NurbsCurve rCurve = new RHG.NurbsCurve(3, false, bCurve.Degree() + 1, ctrlPts.Count); for (int i = 0; i < knots.Count; i++) { rCurve.Knots[i] = knots[i]; } for (int i = 0; i < ctrlPts.Count; i++) { BHG.Point pt = ctrlPts[i]; rCurve.Points.SetPoint(i, pt.X, pt.Y, pt.Z, weights[i]); } return(rCurve); }
public static List <KML.Polygon> ToKML(this BHG.Mesh mesh, GeoReference geoReference) { mesh = mesh.Rotate(geoReference.Reference, BHG.Vector.ZAxis, geoReference.NorthVector.SignedAngle(BHG.Vector.YAxis, BHG.Vector.ZAxis)); List <KML.Polygon> polygons = new List <KML.Polygon>(); foreach (BHG.Face face in mesh.Faces) { List <double> coords = new List <double>(); List <BHG.Point> points = new List <BHG.Point> { mesh.Vertices[face.A].DeepClone(), mesh.Vertices[face.B].DeepClone(), mesh.Vertices[face.C].DeepClone(), mesh.Vertices[face.A].DeepClone() }; if (face.D > -1) { points.Insert(3, mesh.Vertices[face.D].DeepClone()); } foreach (BHG.Point p in points) { BHG.Point kmlpoint = p.ToLatLon(geoReference); coords.Add(kmlpoint.X); coords.Add(kmlpoint.Y); coords.Add(kmlpoint.Z); } KML.Polygon polygon = new KML.Polygon(); polygon.AltitudeMode = geoReference.AltitudeMode.ToKML(); polygon.OuterBoundaryIs.LinearRing.Coordinates = coords.ToArray(); polygons.Add(polygon); } return(polygons); }
public static TBD.TasPoint ToTAS(this BHG.Point point, TBD.TasPoint tbdPoint) { tbdPoint.x = (float)point.X; tbdPoint.y = (float)point.Y; tbdPoint.z = (float)point.Z; return(tbdPoint); }
/***************************************************/ /**** Public Methods - Vectors ****/ /***************************************************/ public static RHG.Point3d ToRhino(this BHG.Point point) { if (point == null) { return(default(RHG.Point3d)); } return(new RHG.Point3d(point.X, point.Y, point.Z)); }
/***************************************************/ public static bool IsEqual(this BHG.Point bhPoint, RHG.ControlPoint rhPoint, double tolerance = BHG.Tolerance.Distance) { if (bhPoint == null & rhPoint.Equals(default(RHG.ControlPoint))) { return(true); } return(Math.Abs(bhPoint.X - rhPoint.Location.X) < tolerance && Math.Abs(bhPoint.Y - rhPoint.Location.Y) < tolerance && Math.Abs(bhPoint.Z - rhPoint.Location.Z) < tolerance); }
/***************************************************/ public static bool IsEqual(this BHG.Point bhPoint, RHG.Point3f rhPoint, double tolerance = BHG.Tolerance.Distance) { if (bhPoint == null & rhPoint == default(RHG.Point3f)) { return(true); } return(Math.Abs(bhPoint.X - rhPoint.X) < tolerance && Math.Abs(bhPoint.Y - rhPoint.Y) < tolerance && Math.Abs(bhPoint.Z - rhPoint.Z) < tolerance); }
public static SpecklePoint ToSpeckle(this BHG.Point bhomPoint) { if (bhomPoint == null) { return(default(SpecklePoint)); } SpecklePoint specklePoint = new SpecklePoint(bhomPoint.X, bhomPoint.Y, bhomPoint.Z); return(specklePoint); }
/***************************************************/ 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); } }
public static BHX.CartesianPoint ToGBXML(this BHG.Point pt) { BHX.CartesianPoint cartPoint = new BHX.CartesianPoint(); List <string> coord = new List <string>(); coord.Add(Math.Round(pt.X, 4).ToString()); coord.Add(Math.Round(pt.Y, 4).ToString()); coord.Add(Math.Round(pt.Z, 4).ToString()); cartPoint.Coordinate = coord.ToArray(); return(cartPoint); }
public static BHG.Point FromGBXML(this BHX.CartesianPoint pt) { BHG.Point bhomPt = new BHG.Point(); try { bhomPt.X = (pt.Coordinate.Length >= 1 ? System.Convert.ToDouble(pt.Coordinate[0]) : 0); bhomPt.Y = (pt.Coordinate.Length >= 2 ? System.Convert.ToDouble(pt.Coordinate[1]) : 0); bhomPt.Z = (pt.Coordinate.Length >= 3 ? System.Convert.ToDouble(pt.Coordinate[2]) : 0); } catch { } return(bhomPt); }
public static BHX.CartesianPoint ToGBXML(this BHG.Point pt, GBXMLSettings settings) { BHX.CartesianPoint cartPoint = new BHX.CartesianPoint(); List <string> coord = new List <string>(); coord.Add(Math.Round(pt.X, settings.RoundingSettings.GeometricPoints).ToString()); coord.Add(Math.Round(pt.Y, settings.RoundingSettings.GeometricPoints).ToString()); coord.Add(Math.Round(pt.Z, settings.RoundingSettings.GeometricPoints).ToString()); cartPoint.Coordinate = coord.ToArray(); return(cartPoint); }
public static KML.Point ToKML(this BHG.Point point, GeoReference geoReference) { BHG.Point latlon = point.ToLatLon(geoReference); List <double> coords = new List <double>() { latlon.X, latlon.Y, latlon.Z }; KML.Point kmlPoint = new KML.Point(); kmlPoint.AltitudeMode = geoReference.AltitudeMode.ToKML(); kmlPoint.Coordinates = coords.ToArray(); return(kmlPoint); }
/***************************************************/ public static bool SetLocation(this Element element, BH.oM.Geometry.Point point, RevitSettings settings) { LocationPoint location = element.Location as LocationPoint; if (location == null || location.IsReadOnly) { return(false); } XYZ bHoMPoint = point.ToRevit(); if (!location.Point.IsAlmostEqualTo(bHoMPoint, settings.DistanceTolerance)) { location.Point = bHoMPoint; return(true); } return(false); }
private static List <BH.oM.Geometry.Line> MatchRevitOrder(List <BH.oM.Geometry.Line> linesToMatch, MEPCurve reference) { LocationCurve locationCurve = reference.Location as LocationCurve; Curve curve = locationCurve.Curve; BH.oM.Geometry.Point referenceStart = curve.GetEndPoint(0).PointFromRevit().RoundCoordinates(4); BH.oM.Geometry.Point referenceEnd = curve.GetEndPoint(1).PointFromRevit().RoundCoordinates(4); List <BH.oM.Geometry.Point> controlPoints = linesToMatch.SelectMany(x => x.ControlPoints()).ToList().CullDuplicates(); Polyline polyline = BH.Engine.Geometry.Create.Polyline(controlPoints); if (referenceStart.IsEqual(polyline.StartPoint()) || referenceEnd.IsEqual(polyline.EndPoint())) { return(polyline.SubParts()); } else { return(polyline.Flip().SubParts()); } }
private static List <BHG.Point> ToPoints(this IEnumerable <double> arr) { if (arr.Count() % 3 != 0) { throw new Exception("Array malformed: length%3 != 0."); } List <BHG.Point> points = new List <BHG.Point>(); var asArray = arr.ToArray(); for (int i = 2, k = 0; i < arr.Count(); i += 3) { points[k++] = new BHG.Point { X = asArray[i - 2], Y = asArray[i - 1], Z = asArray[i] } } ; return(points); } }
public static BHG.Point ToLatLon(this BHG.Point point, GeoReference geoReference) { BHG.Vector vector = point - geoReference.Reference; //vector in plane vector.Z = 0; double degLatInM = 10000000.0 / 90; double bearing = vector.SignedAngle(BHG.Vector.YAxis, BHG.Vector.ZAxis); double DeltaNorth = vector.Length() * Math.Cos(bearing) / degLatInM; double DeltaEast = vector.Length() * Math.Sin(bearing) / Math.Cos(geoReference.ReferenceLatitude * Math.PI / 180) / degLatInM; if (geoReference.AltitudeMode == AltitudeMode.Absolute) { point.Z += geoReference.ReferenceAltitude; } return(new BHG.Point() { X = geoReference.ReferenceLongitude + DeltaEast, Y = geoReference.ReferenceLatitude + DeltaNorth, Z = point.Z }); //https://gis.stackexchange.com/questions/5821/calculating-latitude-longitude-x-miles-from-point }
/***************************************************/ private static Dictionary <PlanarSurface, List <PlanarSurface> > PanelSurfaces_LinkDocument(this HostObject hostObject, IEnumerable <ElementId> insertsToIgnore = null, RevitSettings settings = null) { List <Autodesk.Revit.DB.Face> faces = hostObject.ILinkPanelFaces(settings); List <PlanarFace> planarFaces = faces.Where(x => x is PlanarFace).Cast <PlanarFace>().ToList(); if (faces.Count != planarFaces.Count) { BH.Engine.Reflection.Compute.RecordWarning($"Some faces of the link element were not planar and could not be retrieved.\n ElementId: {hostObject.Id} Document: {hostObject.Document.PathName}"); } Dictionary <PlanarSurface, List <PlanarSurface> > result = new Dictionary <PlanarSurface, List <PlanarSurface> >(); List <Autodesk.Revit.DB.Face> edgeFaces = null; if (insertsToIgnore != null && insertsToIgnore.Any()) { edgeFaces = hostObject.Faces(new Options(), settings).Where(x => hostObject.GetGeneratingElementIds(x).Any(y => insertsToIgnore.Any(z => y.IntegerValue == z.IntegerValue))).ToList(); } foreach (PlanarFace pf in planarFaces) { ICurve outline = null; List <ICurve> openings = new List <ICurve>(); int k = 0; foreach (EdgeArray ea in pf.EdgeLoops) { k++; PolyCurve loop = new PolyCurve(); if (edgeFaces != null) { List <ICurve> edges = new List <ICurve>(); foreach (Edge e in ea) { Curve crv = e.AsCurveFollowingFace(pf); if (!crv.IsEdge(edgeFaces, settings)) { edges.Add(crv.IFromRevit()); } } for (int i = edges.Count - 1; i > 0; i--) { BH.oM.Geometry.Point pt1 = edges[i - 1].IEndPoint(); BH.oM.Geometry.Point pt2 = edges[i].IStartPoint(); if (pt1.Distance(pt2) > settings.DistanceTolerance) { edges.Insert(i, new BH.oM.Geometry.Line { Start = pt1, End = pt2 }); } } if (edges.Count != 0) { BH.oM.Geometry.Point end = edges.Last().IEndPoint(); BH.oM.Geometry.Point start = edges[0].IStartPoint(); if (end.Distance(start) > settings.DistanceTolerance) { edges.Add(new BH.oM.Geometry.Line { Start = end, End = start }); } loop.Curves = edges; } } else { foreach (Edge e in ea) { loop.Curves.Add(e.AsCurveFollowingFace(pf).IFromRevit()); } } if (loop.Curves.Count == 0) { continue; } if (k == 1) { outline = loop; } else { openings.Add(loop); } } if (outline != null) { result.Add(new PlanarSurface(outline, new List <ICurve>()), openings.Select(x => new PlanarSurface(x, new List <ICurve>())).ToList()); } } return(result); }
private static double[] ToArray(this BHG.Point pt) { return(new double[] { pt.X, pt.Y, pt.Z }); }
/***************************************************/ /**** Public Methods - Vectors ****/ /***************************************************/ public static void RenderWires(BHG.Point point, Rhino.Display.DisplayPipeline pipeline, Color bhColour) { pipeline.DrawPoint(point.ToRhino(), Rhino.Display.PointStyle.Simple, 4, bhColour); }
public static Point3d ToOSM(this BHG.Point point) { return(new Point3d(point.X, point.Y, point.Z)); }
/***************************************************/ private static FreeFormProfile FreeFormProfileFromRevit(this FamilySymbol familySymbol, RevitSettings settings) { XYZ direction; if (familySymbol.Family.FamilyPlacementType == FamilyPlacementType.CurveDrivenStructural) { direction = XYZ.BasisX; } else if (familySymbol.Family.FamilyPlacementType == FamilyPlacementType.TwoLevelsBased) { direction = XYZ.BasisZ; } else { BH.Engine.Reflection.Compute.RecordWarning("The profile of a family type could not be found. ElementId: " + familySymbol.Id.IntegerValue.ToString()); return(null); } // Check if one and only one solid exists to make sure that the column is a single piece Solid solid = null; Options options = new Options(); options.DetailLevel = ViewDetailLevel.Fine; options.IncludeNonVisibleObjects = false; // Activate the symbol temporarily if not active, then extract its geometry (open either transaction or subtransaction, depending on whether one is already open). if (!familySymbol.IsActive) { Document doc = familySymbol.Document; if (!doc.IsModifiable) { using (Transaction tempTransaction = new Transaction(doc, "Temp activate family symbol")) { tempTransaction.Start(); familySymbol.Activate(); doc.Regenerate(); solid = familySymbol.get_Geometry(options).SingleSolid(); if (solid != null) { solid = SolidUtils.Clone(solid); } tempTransaction.RollBack(); } } else { using (SubTransaction tempTransaction = new SubTransaction(doc)) { tempTransaction.Start(); familySymbol.Activate(); doc.Regenerate(); solid = familySymbol.get_Geometry(options).SingleSolid(); if (solid != null) { solid = SolidUtils.Clone(solid); } tempTransaction.RollBack(); } } } else { solid = familySymbol.get_Geometry(options).SingleSolid(); } if (solid == null) { BH.Engine.Reflection.Compute.RecordWarning("The profile of a family type could not be found because it is empty or it consists of more than one solid. ElementId: " + familySymbol.Id.IntegerValue.ToString()); return(null); } Autodesk.Revit.DB.Face face = null; foreach (Autodesk.Revit.DB.Face f in solid.Faces) { if (f is PlanarFace && (f as PlanarFace).FaceNormal.Normalize().IsAlmostEqualTo(-direction, 0.001)) { if (face == null) { face = f; } else { BH.Engine.Reflection.Compute.RecordWarning("The profile of a family type could not be found. ElementId: " + familySymbol.Id.IntegerValue.ToString()); return(null); } } } if (face == null) { BH.Engine.Reflection.Compute.RecordWarning("The profile of a family type could not be found. ElementId: " + familySymbol.Id.IntegerValue.ToString()); return(null); } List <ICurve> profileCurves = new List <ICurve>(); foreach (EdgeArray curveArray in (face as PlanarFace).EdgeLoops) { foreach (Edge c in curveArray) { ICurve curve = c.AsCurve().IFromRevit(); if (curve == null) { BH.Engine.Reflection.Compute.RecordWarning("The profile of a family type could not be converted due to curve conversion issues. ElementId: " + familySymbol.Id.IntegerValue.ToString()); return(null); } profileCurves.Add(curve); } } if (profileCurves.Count != 0) { BH.oM.Geometry.Point centroid = solid.ComputeCentroid().PointFromRevit(); Vector tan = direction.VectorFromRevit().Normalise(); // Adjustment of the origin to global (0,0,0). Vector adjustment = oM.Geometry.Point.Origin - centroid + (centroid - profileCurves[0].IStartPoint()).DotProduct(tan) * tan; if (adjustment.Length() > settings.DistanceTolerance) { profileCurves = profileCurves.Select(x => x.ITranslate(adjustment)).ToList(); } // Check if the curves are in the horizontal plane, if not then align them. if (familySymbol.Family.FamilyPlacementType == FamilyPlacementType.CurveDrivenStructural) { // First rotate the profile to align its local plane with global XY, then rotate to align its local Z with global Y. double angle = Math.PI * 0.5; profileCurves = profileCurves.Select(x => x.IRotate(oM.Geometry.Point.Origin, Vector.YAxis, angle)).ToList(); profileCurves = profileCurves.Select(x => x.IRotate(oM.Geometry.Point.Origin, Vector.ZAxis, angle)).ToList(); } } return(BHS.Create.FreeFormProfile(profileCurves)); }
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 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 List <BH.oM.Geometry.Line> CeilingPattern(this Material revitMaterial, PlanarSurface surface, RevitSettings settings, XYZ origin = null, double angle = 0) { surface = surface.Rotate(BH.oM.Geometry.Point.Origin, Vector.ZAxis, -angle); BoundingBox box = surface.IBounds(); origin = Transform.CreateRotation(XYZ.BasisZ, -angle).OfPoint(origin); double z = surface.ExternalBoundary.IControlPoints().Max(x => x.Z); double yLength = (box.Max.Y - box.Min.Y) / 2; double xLength = (box.Max.X - box.Min.X) / 2; double maxBoxLength = box.Min.Distance(box.Max); BH.oM.Geometry.Line leftLine = new oM.Geometry.Line { Start = new oM.Geometry.Point { X = box.Min.X, Y = box.Min.Y, Z = z }, End = new oM.Geometry.Point { X = box.Min.X, Y = box.Max.Y, Z = z }, }; BH.oM.Geometry.Line rightLine = new oM.Geometry.Line { Start = new oM.Geometry.Point { X = box.Max.X, Y = box.Min.Y, Z = z }, End = new oM.Geometry.Point { X = box.Max.X, Y = box.Max.Y, Z = z }, }; List <BH.oM.Geometry.Line> boundarySegments = surface.ExternalBoundary.ICollapseToPolyline(settings.AngleTolerance).SubParts().ToList(); List <BH.oM.Geometry.Line> patterns = new List <BH.oM.Geometry.Line>(); FillPatternElement fillPatternElement = null; #if (REVIT2020 || REVIT2021) fillPatternElement = revitMaterial.Document.GetElement(revitMaterial.SurfaceForegroundPatternId) as FillPatternElement; #else fillPatternElement = revitMaterial.Document.GetElement(revitMaterial.SurfacePatternId) as FillPatternElement; #endif if (fillPatternElement != null) { FillPattern fillPattern = fillPatternElement.GetFillPattern(); if (fillPattern == null || fillPattern.IsSolidFill) { return(new List <oM.Geometry.Line>()); //Skip solid filled patterns } IList <FillGrid> fillGridList = fillPattern.GetFillGrids(); foreach (FillGrid grid in fillGridList) { double offset = grid.Offset.ToSI(UnitType.UT_Length); double currentY = ((int)((box.Min.Y - yLength) / offset)) * offset; double currentX = ((int)((box.Min.X - xLength) / offset)) * offset; double minNum = currentX; double maxNum = (box.Max.X + xLength); if (grid.Angle.ToSI(UnitType.UT_Angle) > settings.AngleTolerance) { minNum = currentY; maxNum = (box.Max.Y + yLength); } if (origin != null) { if (grid.Angle.ToSI(UnitType.UT_Angle) > settings.AngleTolerance) { minNum += (origin.Y % grid.Offset).ToSI(UnitType.UT_Length); } else { minNum += (origin.X % grid.Offset).ToSI(UnitType.UT_Length); } } while ((minNum + offset) < maxNum) { BH.oM.Geometry.Point pt = new oM.Geometry.Point { X = minNum + offset, Y = box.Min.Y, Z = z }; BH.oM.Geometry.Point pt2 = new oM.Geometry.Point { X = minNum + offset, Y = box.Max.Y, Z = z }; BH.oM.Geometry.Line pline = new oM.Geometry.Line { Start = pt, End = pt2 }; if (grid.Angle.ToSI(UnitType.UT_Angle) > settings.AngleTolerance) { BH.oM.Geometry.Point rotatePt = pline.Centroid(); pline = pline.Rotate(rotatePt, Vector.ZAxis, grid.Angle.ToSI(UnitType.UT_Angle)); pline.Start.Y = minNum + offset; pline.End.Y = minNum + offset; BH.oM.Geometry.Point intersect = pline.LineIntersection(leftLine, true); if (intersect != null) { pline.Start = intersect; } intersect = pline.LineIntersection(rightLine, true); if (intersect != null) { pline.End = intersect; } Vector v1 = pline.End - pline.Start; //From start TO end v1 *= maxBoxLength; Vector v2 = pline.Start - pline.End; //From end TO start v2 *= maxBoxLength; pline.Start = pline.Start.Translate(v2); pline.End = pline.End.Translate(v1); } List <BH.oM.Geometry.Point> intersections = new List <oM.Geometry.Point>(); foreach (BH.oM.Geometry.Line l in boundarySegments) { BH.oM.Geometry.Point p = pline.LineIntersection(l); if (p != null) { intersections.Add(p); } } List <BH.oM.Geometry.Line> lines = new List <oM.Geometry.Line>(); if (intersections.Count > 0) { lines = pline.SplitAtPoints(intersections); } else { lines.Add(pline); } foreach (BH.oM.Geometry.Line l in lines) { List <BH.oM.Geometry.Point> pts = l.ControlPoints(); pts.Add(l.Centroid()); if (surface.ExternalBoundary.IIsContaining(pts, true)) { patterns.Add(l.Rotate(BH.oM.Geometry.Point.Origin, Vector.ZAxis, angle)); } } minNum += offset; } } } patterns.AddRange(boundarySegments.Select(x => x.Rotate(BH.oM.Geometry.Point.Origin, Vector.ZAxis, angle))); //Close off the ceiling pattern for its own use return(patterns); }
/***************************************************/ /**** Public Methods - Vectors ****/ /***************************************************/ public static void RenderMeshes(BHG.Point point, Rhino.Display.DisplayPipeline pipeline, DisplayMaterial material) { return; }