/***************************************************/ /**** Public methods ****/ /***************************************************/ public static IFramingElementProperty FramingElementProperty(this FamilyInstance familyInstance, RevitSettings settings, Dictionary <string, List <IBHoMObject> > refObjects = null) { if (familyInstance == null || familyInstance.Symbol == null) { return(null); } ConstantFramingProperty framingProperty = refObjects.GetValue <ConstantFramingProperty>(familyInstance.Id); if (framingProperty != null) { return(framingProperty); } // Convert the material to BHoM. ElementId structuralMaterialId = familyInstance.StructuralMaterialId; if (structuralMaterialId.IntegerValue < 0) { structuralMaterialId = familyInstance.Symbol.LookupParameterElementId(BuiltInParameter.STRUCTURAL_MATERIAL_PARAM); } Material revitMaterial = familyInstance.Document.GetElement(structuralMaterialId) as Material; if (revitMaterial == null) { revitMaterial = familyInstance.Category.Material; } string materialGrade = familyInstance.MaterialGrade(settings); BH.oM.Physical.Materials.Material material = revitMaterial.MaterialFromRevit(materialGrade, settings, refObjects); // If Revit material is null, rename the BHoM material based on material type of framing family. if (material != null && revitMaterial == null) { material.Name = String.Format("Unknown {0} Material", familyInstance.StructuralMaterialType); material.Properties.Add(familyInstance.StructuralMaterialType.EmptyMaterialFragment(materialGrade)); } IProfile profile = familyInstance.Symbol.ProfileFromRevit(settings, refObjects); if (profile == null) { familyInstance.Symbol.NotConvertedWarning(); } double rotation = familyInstance.OrientationAngle(settings); framingProperty = BH.Engine.Physical.Create.ConstantFramingProperty(profile, material, rotation, familyInstance.Symbol.Name); //Set identifiers, parameters & custom data framingProperty.SetIdentifiers(familyInstance.Symbol); framingProperty.CopyParameters(familyInstance.Symbol, settings.ParameterSettings); framingProperty.SetProperties(familyInstance.Symbol, settings.ParameterSettings); refObjects.AddOrReplace(familyInstance.Id, framingProperty); return(framingProperty); }
/***************************************************/ private static MaterialComposition MaterialComposition(this ConstantFramingProperty prop) { if (prop.Material == null) { Engine.Reflection.Compute.RecordError("The ConstantFramingProperty MaterialComposition could not be calculated as no Material has been assigned."); return(null); } return((MaterialComposition)prop.Material); }
public static IGeometry Geometry3D(this IFramingElement framingElement) { if (framingElement == null) { BH.Engine.Reflection.Compute.RecordError("Cannot query the 3D Geometry of a null framing element."); return(null); } if (framingElement.Location == null) { BH.Engine.Reflection.Compute.RecordError($"Cannot compute the Geometry3D for this {nameof(IFramingElement)} because its `{nameof(IFramingElement.Location)}` is null."); return(null); } Line line = framingElement.Location as Line; if (line == null) { Polyline pl = framingElement.Location as Polyline; if (pl != null) { line = new Line() { Start = pl.ControlPoints.First(), End = pl.ControlPoints.Last() }; } if (pl == null || (pl != null && pl.ControlPoints.Count() > 2)) { BH.Engine.Reflection.Compute.RecordWarning($"Geometry3D for {nameof(IFramingElement)} currently works only if it has its {nameof(IFramingElement.Location)} defined as a {nameof(Line)}. Proceeding by taking Start/End point of the provided {framingElement.Location.GetType().Name}."); } } Vector extrusionVec = BH.Engine.Geometry.Create.Vector(line.Start, line.End); Vector normal = line.ElementNormal(0); IFramingElementProperty prop = framingElement.Property; ConstantFramingProperty constantFramingProperty = prop as ConstantFramingProperty; if (constantFramingProperty == null) { BH.Engine.Reflection.Compute.RecordError($"Geometry3D for {nameof(IFramingElement)} currently works only if its {nameof(IFramingElement.Property)} is of type {nameof(ConstantFramingProperty)}."); return(null); } List <ICurve> profileToExtrude = constantFramingProperty.Profile.Edges.ToList(); if (profileToExtrude == null || !profileToExtrude.Any()) { BH.Engine.Reflection.Compute.RecordError($"Geometry3D error: could not gather the profile curve to be extruded for this {framingElement.GetType().Name}."); return(null); } TransformMatrix totalTransform = SectionTranformation(line.Start, extrusionVec.Normalise(), normal); return(Extrude(profileToExtrude, totalTransform, extrusionVec)); }
public static double AverageProfileArea(this ConstantFramingProperty framingProperty) { if (framingProperty.Profile == null) { Engine.Reflection.Compute.RecordError("The framingProperty Average Profile Area could not be calculated as no Profile has been assigned. Returning zero Area."); return(0); } return(framingProperty.Profile.Area()); }
/***************************************************/ public static bool SetLocation(this FamilyInstance element, IFramingElement framingElement, RevitSettings settings) { if (!(typeof(IFramingElement).BuiltInCategories().Contains((BuiltInCategory)element.Category.Id.IntegerValue))) { return(false); } double rotation = 0; ConstantFramingProperty framingProperty = framingElement.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}", framingElement.BHoM_Guid)); } else { rotation = ((ConstantFramingProperty)framingElement.Property).OrientationAngle; } if (element.LookupParameterInteger(BuiltInParameter.YZ_JUSTIFICATION) == 1) { BH.Engine.Reflection.Compute.RecordWarning(String.Format("Pushing of framing elements with non-uniform offsets at ends is currently not supported. yz Justification parameter has been set to Uniform. Revit ElementId: {0}", element.Id)); element.SetParameter(BuiltInParameter.YZ_JUSTIFICATION, 0); element.Document.Regenerate(); } bool updated = element.SetLocation(framingElement.Location, settings); element.Document.Regenerate(); double rotationDifference = element.OrientationAngleFraming(settings) - rotation; if (Math.Abs(rotationDifference) > settings.AngleTolerance) { double newRotation = (element.LookupParameterDouble(BuiltInParameter.STRUCTURAL_BEND_DIR_ANGLE) + rotationDifference).NormalizeAngleDomain(); updated |= element.SetParameter(BuiltInParameter.STRUCTURAL_BEND_DIR_ANGLE, newRotation); element.Document.Regenerate(); } ICurve transformedCurve = framingElement.AdjustedLocationCurveFraming((FamilyInstance)element, settings); updated |= element.SetLocation(transformedCurve, settings); return(updated); }
public static ICurve TopCentreline(this IFramingElement element) { if (element == null) { BH.Engine.Reflection.Compute.RecordError("Cannot query the top centreline of a null framing element."); return(null); } ICurve location = element.Location; Vector normal = null; try { normal = BH.Engine.Physical.Query.Normal(element); } catch { Engine.Reflection.Compute.RecordError("IFramingElement must have linear location line."); return(null); } if (normal == null) { Engine.Reflection.Compute.RecordError("Was not able to compute element normal."); return(null); } if (element.Property is ConstantFramingProperty) { ConstantFramingProperty constantProperty = element.Property as ConstantFramingProperty; IProfile profile = constantProperty.Profile; BoundingBox profileBounds = profile.Edges.Bounds(); return(location.ITranslate(normal * profileBounds.Max.Y)); } else { Engine.Reflection.Compute.RecordError("Element does not have a suitable framing property, so the section height could not be calculated."); return(null); } }
public static FrameEdge Transform(this FrameEdge edge, TransformMatrix transform, double tolerance = Tolerance.Distance) { if (!transform.IsRigidTransformation(tolerance)) { BH.Engine.Reflection.Compute.RecordError("Transformation failed: only rigid body transformations are currently supported."); return(null); } FrameEdge result = edge.ShallowClone(); result.Curve = result.Curve.ITransform(transform); if (edge.FrameEdgeProperty != null) { if (edge.Curve is Line) { Line lineBefore = (Line)edge.Curve; Line lineAfter = (Line)result.Curve; List <ConstantFramingProperty> newProperties = new List <ConstantFramingProperty>(); foreach (ConstantFramingProperty property in edge.FrameEdgeProperty.SectionProperties) { ConstantFramingProperty newProperty = property.ShallowClone(); Vector normalBefore = lineBefore.ElementNormal(property.OrientationAngle); Vector normalAfter = normalBefore.Transform(transform); newProperty.OrientationAngle = normalAfter.OrientationAngleLinear(lineAfter); newProperties.Add(newProperty); } edge.FrameEdgeProperty.SectionProperties = newProperties; } else if (!edge.Curve.IIsPlanar(tolerance)) { BH.Engine.Reflection.Compute.RecordWarning($"The element's location is a nonlinear, nonplanar curve. Correctness of orientation angle after transform could not be ensured in 100%. BHoM_Guid: {edge.BHoM_Guid}"); } } return(result); }
public static IFramingElement Transform(this IFramingElement framingElement, TransformMatrix transform, double tolerance = Tolerance.Distance) { if (!transform.IsRigidTransformation(tolerance)) { BH.Engine.Reflection.Compute.RecordError("Transformation failed: only rigid body transformations are currently supported."); return(null); } IFramingElement result = framingElement.ShallowClone(); result.Location = result.Location.ITransform(transform); ConstantFramingProperty property = result.Property as ConstantFramingProperty; if (property == null) { BH.Engine.Reflection.Compute.RecordWarning($"Orientation angle of the IFramingElement has not been transformed because its property is not ConstantFramingProperty. BHoM_Guid: {framingElement.BHoM_Guid}"); } else { if (framingElement.Location is Line) { ConstantFramingProperty newProperty = property.ShallowClone(); Vector normalBefore = ((Line)framingElement.Location).ElementNormal(property.OrientationAngle); Vector normalAfter = normalBefore.Transform(transform); newProperty.OrientationAngle = normalAfter.OrientationAngleLinear((Line)result.Location); result.Property = newProperty; } else if (!framingElement.Location.IIsPlanar(tolerance)) { BH.Engine.Reflection.Compute.RecordWarning($"The element's location is a nonlinear, nonplanar curve. Correctness of orientation angle after transform could not be ensured in 100%. BHoM_Guid: {framingElement.BHoM_Guid}"); } } return(result); }
/***************************************************/ /**** Public methods ****/ /***************************************************/ public static IFramingElementProperty FramingElementProperty(this FamilyInstance familyInstance, RevitSettings settings, Dictionary <string, List <IBHoMObject> > refObjects = null) { if (familyInstance == null || familyInstance.Symbol == null) { return(null); } ConstantFramingProperty framingProperty = refObjects.GetValue <ConstantFramingProperty>(familyInstance.Id); if (framingProperty != null) { return(framingProperty); } // Convert the material to BHoM. ElementId structuralMaterialId = familyInstance.StructuralMaterialId; if (structuralMaterialId.IntegerValue < 0) { structuralMaterialId = familyInstance.Symbol.LookupParameterElementId(BuiltInParameter.STRUCTURAL_MATERIAL_PARAM); } Material revitMaterial = familyInstance.Document.GetElement(structuralMaterialId) as Material; if (revitMaterial == null) { revitMaterial = familyInstance.Category.Material; } string materialGrade = familyInstance.MaterialGrade(settings); BH.oM.Physical.Materials.Material material = revitMaterial.MaterialFromRevit(materialGrade, settings, refObjects); // If Revit material is null, rename the BHoM material based on material type of framing family. if (material != null && revitMaterial == null) { material.Name = String.Format("Unknown {0} Material", familyInstance.StructuralMaterialType); material.Properties.Add(familyInstance.StructuralMaterialType.EmptyMaterialFragment(materialGrade)); } IProfile profile = familyInstance.Symbol.ProfileFromRevit(settings, refObjects); if (profile == null) { familyInstance.Symbol.NotConvertedWarning(); } if (familyInstance.Mirrored) { if (profile is FreeFormProfile) { BH.oM.Geometry.Plane mirror = new oM.Geometry.Plane { Normal = BH.oM.Geometry.Vector.XAxis }; profile = BH.Engine.Spatial.Create.FreeFormProfile(profile.Edges.Select(x => x.IMirror(mirror))); } else if (profile is AngleProfile) { AngleProfile angle = ((AngleProfile)profile); profile = BH.Engine.Spatial.Create.AngleProfile(angle.Height, angle.Width, angle.WebThickness, angle.FlangeThickness, angle.RootRadius, angle.ToeRadius, true, false); } else if (profile is ChannelProfile) { ChannelProfile channel = ((ChannelProfile)profile); profile = BH.Engine.Spatial.Create.ChannelProfile(channel.Height, channel.FlangeWidth, channel.WebThickness, channel.FlangeThickness, channel.RootRadius, channel.ToeRadius, true); } } double rotation = familyInstance.OrientationAngle(settings); framingProperty = BH.Engine.Physical.Create.ConstantFramingProperty(profile, material, rotation, familyInstance.Symbol.Name); //Set identifiers, parameters & custom data framingProperty.SetIdentifiers(familyInstance.Symbol); framingProperty.CopyParameters(familyInstance.Symbol, settings.ParameterSettings); framingProperty.SetProperties(familyInstance.Symbol, settings.ParameterSettings); refObjects.AddOrReplace(familyInstance.Id, framingProperty); return(framingProperty); }
/***************************************************/ 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); }