/***************************************************/ 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 Methods ****/ /***************************************************/ public static Bar FromRFEM(this rf.Member member, rf.Line line, ISectionProperty sectionProperty) { rf.Point3D sPt = line.ControlPoints.First(); rf.Point3D ePt = line.ControlPoints.Last(); BH.oM.Geometry.Line ln = new oM.Geometry.Line() { Start = new oM.Geometry.Point() { X = sPt.X, Y = sPt.Y, Z = sPt.Z }, End = new oM.Geometry.Point() { X = ePt.X, Y = ePt.Y, Z = ePt.Z } }; Bar bhBar = BH.Engine.Structure.Create.Bar(ln, sectionProperty, member.Rotation.Angle); bhBar.SetAdapterId(typeof(RFEMId), member.No); return(bhBar); }
/***************************************************/ 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 static bool SetLocation(this FamilyInstance element, Column column, RevitSettings settings) { if (!(typeof(Column).BuiltInCategories().Contains((BuiltInCategory)element.Category.Id.IntegerValue))) { return(false); } oM.Geometry.Line columnLine = column.Location as oM.Geometry.Line; if (columnLine == null) { BH.Engine.Reflection.Compute.RecordError(String.Format("Location has not been updated, only linear columns are allowed in Revit. Revit ElementId: {0} BHoM_Guid: {1}", element.Id, column.BHoM_Guid)); return(false); } if (columnLine.Start.Z >= columnLine.End.Z) { BH.Engine.Reflection.Compute.RecordError(String.Format("Location of the column has not been updated because BHoM column has start above end. Revit ElementId: {0} BHoM_Guid: {1}", element.Id, column.BHoM_Guid)); return(false); } if (1 - columnLine.Direction().DotProduct(Vector.ZAxis) > settings.AngleTolerance && element.LookupParameterInteger(BuiltInParameter.SLANTED_COLUMN_TYPE_PARAM) == 0) { BH.Engine.Reflection.Compute.RecordWarning(String.Format("Column style has been set to Vertical, but its driving curve is slanted. Column style changed to Slanted. Revit ElementId: {0} BHoM_Guid: {1}", element.Id, column.BHoM_Guid)); element.SetParameter(BuiltInParameter.SLANTED_COLUMN_TYPE_PARAM, 2); element.Document.Regenerate(); } bool updated = false; if (element.IsSlantedColumn) { updated |= element.SetLocation(columnLine, settings); Output <double, double> extensions = element.ColumnExtensions(settings); double startExtension = -extensions.Item1; double endExtension = -extensions.Item2; if (Math.Abs(startExtension) > settings.DistanceTolerance || Math.Abs(endExtension) > settings.DistanceTolerance) { element.SetLocation(columnLine.Extend(startExtension, endExtension), settings); updated = true; } } else { double locationZ = ((LocationPoint)element.Location).Point.Z.ToSI(UnitType.UT_Length); updated |= element.SetLocation(new oM.Geometry.Point { X = columnLine.Start.X, Y = columnLine.Start.Y, Z = locationZ }, settings); Parameter baseLevelParam = element.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_PARAM); Parameter topLevelParam = element.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_PARAM); Parameter baseOffsetParam = element.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM); Parameter topOffsetParam = element.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM); Level baseLevel = element.Document.GetElement(baseLevelParam.AsElementId()) as Level; Level topLevel = element.Document.GetElement(topLevelParam.AsElementId()) as Level; double baseElevation = (baseLevel.ProjectElevation + baseOffsetParam.AsDouble()).ToSI(UnitType.UT_Length); double topElevation = (topLevel.ProjectElevation + topOffsetParam.AsDouble()).ToSI(UnitType.UT_Length); if (Math.Abs(baseElevation - columnLine.Start.Z) > settings.DistanceTolerance) { element.SetParameter(BuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM, columnLine.Start.Z.FromSI(UnitType.UT_Length) - baseLevel.ProjectElevation, false); updated = true; } if (Math.Abs(topElevation - columnLine.End.Z) > settings.DistanceTolerance) { element.SetParameter(BuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM, columnLine.End.Z.FromSI(UnitType.UT_Length) - topLevel.ProjectElevation, false); updated = true; } } double rotation = 0; ConstantFramingProperty framingProperty = column.Property as ConstantFramingProperty; if (framingProperty == null) { BH.Engine.Reflection.Compute.RecordWarning(String.Format("BHoM object's property is not a ConstantFramingProperty, therefore its orientation angle could not be retrieved. BHoM_Guid: {0}", column.BHoM_Guid)); } else { rotation = ((ConstantFramingProperty)column.Property).OrientationAngle; } double rotationDifference = element.OrientationAngleColumn(settings) - rotation; if (Math.Abs(rotationDifference) > settings.AngleTolerance) { double rotationParamValue = element.LookupParameterDouble(BuiltInParameter.STRUCTURAL_BEND_DIR_ANGLE); if (double.IsNaN(rotationParamValue)) { ElementTransformUtils.RotateElement(element.Document, element.Id, columnLine.ToRevit(), -rotationDifference.NormalizeAngleDomain()); updated = true; } else { double newRotation = (rotationParamValue + rotationDifference).NormalizeAngleDomain(); updated |= element.SetParameter(BuiltInParameter.STRUCTURAL_BEND_DIR_ANGLE, newRotation); } } return(updated); }