/// <summary> /// Draws a point around the center of an analysis surface. Useful for sorting/grouping surfaces upstream of a SetSurfaceParameters node. /// </summary> /// <param name="SurfaceId">The ElementId of the surface to create a point from. Get this from the AnalysisZones > CreateFrom* > SurfaceIds output list</param> /// <returns></returns> public static Autodesk.DesignScript.Geometry.Point AnalysisSurfacePoint(ElementId SurfaceId) { //local varaibles Document RvtDoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument.Document; MassSurfaceData surf = null; Autodesk.Revit.DB.ElementId myEnergyModelId = null; //try to get the MassSurfaceData object from the document try { surf = (MassSurfaceData)RvtDoc.GetElement(new Autodesk.Revit.DB.ElementId(SurfaceId.InternalId)); if (surf == null) { throw new Exception(); } } catch (Exception) { throw new Exception("Couldn't find a MassSurfaceData object with Id #: " + SurfaceId.ToString()); } //try to get the element id of the MassEnergyAnalyticalModel - we need this to pull faces from try { myEnergyModelId = surf.ReferenceElementId; if (myEnergyModelId == null) { throw new Exception(); } } catch (Exception) { throw new Exception("Couldn't find a MassEnergyAnalyticalModel object belonging to the Mass instance with Id #: " + surf.ReferenceElementId.ToString()); } //try to get the MassSurfaceData object from the document try { surf = (MassSurfaceData)RvtDoc.GetElement(new Autodesk.Revit.DB.ElementId(SurfaceId.InternalId)); if (surf == null) { throw new Exception(); } } catch (Exception) { throw new Exception("Couldn't find a MassSurfaceData object with Id #: " + SurfaceId.ToString()); } //get the smallest face Autodesk.Revit.DB.Face smallFace = GetSmallestFace(RvtDoc, surf, myEnergyModelId); //get the average point of all points on the face Autodesk.DesignScript.Geometry.Point outPoint = getAveragePointFromFace(smallFace); return(outPoint); }
// get surface ids from zone based on type public static List <EnergyAnalysisForDynamo.ElementId> GetSurfaceIdsFromZoneBasedOnType(MassZone MassZone, string SurfaceTypeName = "Mass Exterior Wall") { //some faces supposedly share massSurfaceData definitions (although i think they are all unique in practice) - here we're pulling out unique data definitions. Dictionary <int, MassSurfaceData> mySurfaceData = new Dictionary <int, MassSurfaceData>(); //get references to all of the faces IList <Reference> faceRefs = MassZone.GetReferencesToEnergyAnalysisFaces(); foreach (var faceRef in faceRefs) { var srfType = faceRef.GetType(); string refType = faceRef.ElementReferenceType.ToString(); //get the element ID of the MassSurfaceData object associated with this face Autodesk.Revit.DB.ElementId id = MassZone.GetMassDataElementIdForZoneFaceReference(faceRef); //add it to our dict if it isn't already there if (!mySurfaceData.ContainsKey(id.IntegerValue)) { var mySurface = MassZone.Document.GetElement(id); // Extra check to make sure the surface is not a mass floor which is // a MassLevelData in REVIT. In Vasari it doesn't make any issues. if (mySurface.Category.Name != "Mass Floor") { MassSurfaceData d = (MassSurfaceData)MassZone.Document.GetElement(id); mySurfaceData.Add(id.IntegerValue, d); } } } //filter by category = mass exterior wall var allSurfsList = mySurfaceData.Values.ToList(); var extSurfList = from n in allSurfsList where n.Category.Name == SurfaceTypeName select n; //list of element Ids to wrap and output List <Autodesk.Revit.DB.ElementId> surfaceIds = extSurfList.Select(e => e.Id).ToList(); //loop over the output lists, and wrap them in our ElementId wrapper class List <ElementId> outSurfaceIds = surfaceIds.Select(e => new ElementId(e.IntegerValue)).ToList(); return(outSurfaceIds); }
/// <summary> /// Draws a mesh in Dynamo representing an analysis surface. Useful when trying to identify a surface to modify. /// </summary> /// <param name="SurfaceId">The ElementId of the surface to draw. Get this from AnalysisZones > CreateFrom* > SurfaceIds output list</param> /// <returns></returns> public static Autodesk.DesignScript.Geometry.Mesh DrawAnalysisSurface(ElementId SurfaceId) { //local varaibles Document RvtDoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument.Document; MassSurfaceData surf = null; Autodesk.Revit.DB.ElementId myEnergyModelId = null; //try to get the MassSurfaceData object from the document try { surf = (MassSurfaceData)RvtDoc.GetElement(new Autodesk.Revit.DB.ElementId(SurfaceId.InternalId)); if (surf == null) { throw new Exception(); } } catch (Exception) { throw new Exception("Couldn't find a MassSurfaceData object with Id #: " + SurfaceId.ToString()); } //try to get the element id of the MassEnergyAnalyticalModel - we need this to pull faces from try { myEnergyModelId = surf.ReferenceElementId; if (myEnergyModelId == null) { throw new Exception(); } } catch (Exception) { throw new Exception("Couldn't find a MassEnergyAnalyticalModel object belonging to the Mass instance with Id #: " + surf.ReferenceElementId.ToString()); } //get the smallest face Autodesk.Revit.DB.Face smallFace = GetSmallestFace(RvtDoc, surf, myEnergyModelId); Autodesk.Revit.DB.Mesh prettyMesh = smallFace.Triangulate(); return(Revit.GeometryConversion.RevitToProtoMesh.ToProtoType(prettyMesh)); }
private static Autodesk.Revit.DB.Face GetLargestFace(Document RvtDoc, MassSurfaceData surf, Autodesk.Revit.DB.ElementId myEnergyModelId) { //the data object contains references to faces. For every face, draw a surface or something with designscript IList <Reference> faceRefs = surf.GetFaceReferences(); Autodesk.Revit.DB.Face bigFace = null; double bigFaceArea = 0.0; foreach (var fr in faceRefs) { //get the smallest face Autodesk.Revit.DB.Face pretty = (Autodesk.Revit.DB.Face)RvtDoc.GetElement(myEnergyModelId).GetGeometryObjectFromReference(fr); if (pretty.Area > bigFaceArea) { bigFaceArea = pretty.Area; bigFace = pretty; } } return(bigFace); }
// get surface ids from analytical energy model based on type public static List <EnergyAnalysisForDynamo.ElementId> GetSurfaceIdsFromMassEnergyAnalyticalModelBasedOnType(MassEnergyAnalyticalModel MassEnergyAnalyticalModel, string SurfaceTypeName = "Mass Exterior Wall") { //get the MassSurfaceData ids of the definitions belonging to external faces //we'll output these, and then try to visualize the faces and change parameters in another component //get references to the faces using the mass - we need these to get at the surface data IList <Reference> faceRefs = MassEnergyAnalyticalModel.GetReferencesToAllFaces(); //some faces supposedly share massSurfaceData definitions (although i think they are all unique in practice) - here we're pulling out unique data definitions. Dictionary <int, MassSurfaceData> mySurfaceData = new Dictionary <int, MassSurfaceData>(); foreach (var fr in faceRefs) { Autodesk.Revit.DB.ElementId id = MassEnergyAnalyticalModel.GetMassSurfaceDataIdForReference(fr); if (!mySurfaceData.ContainsKey(id.IntegerValue)) { MassSurfaceData d = (MassSurfaceData)MassEnergyAnalyticalModel.Document.GetElement(id); mySurfaceData.Add(id.IntegerValue, d); } } //filter by category = mass exterior wall var allSurfsList = mySurfaceData.Values.ToList(); var selectedSurfList = from n in allSurfsList where n.Category.Name == SurfaceTypeName select n; //output list List <Autodesk.Revit.DB.ElementId> SelectedSurfaceIds = new List <Autodesk.Revit.DB.ElementId>(); foreach (var s in selectedSurfList) { SelectedSurfaceIds.Add(s.Id); } List <ElementId> outSelectedSurfaceIds = SelectedSurfaceIds.Select(e => new ElementId(e.IntegerValue)).ToList(); return(outSelectedSurfaceIds); }
private static Autodesk.Revit.DB.Face GetSmallestFace(Document RvtDoc, MassSurfaceData surf, Autodesk.Revit.DB.ElementId myEnergyModelId) { //the data object contains references to faces. For every face, draw a surface or something with designscript IList<Reference> faceRefs = surf.GetFaceReferences(); Autodesk.Revit.DB.Face smallFace = null; double smallFaceArea = 1000000.0; foreach (var fr in faceRefs) { //get the smallest face Autodesk.Revit.DB.Face pretty = (Autodesk.Revit.DB.Face)RvtDoc.GetElement(myEnergyModelId).GetGeometryObjectFromReference(fr); if (pretty.Area < smallFaceArea) { smallFaceArea = pretty.Area; smallFace = pretty; } } return smallFace; }
/// <summary> /// Returns a vector represnting the normal of an analysis surface. Useful for sorting/grouping surfaces upstream of a SetSurfaceParameters node. /// </summary> /// <param name="SurfaceId">The ElementId of the surface to create a vector from. Get this from AnalysisZones > CreateFrom* > SurfaceIds output list</param> /// <returns></returns> public static Autodesk.DesignScript.Geometry.Vector AnalysisSurfaceVector(ElementId SurfaceId) { //local varaibles Document RvtDoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument.Document; MassSurfaceData surf = null; Autodesk.Revit.DB.ElementId myEnergyModelId = null; //try to get the MassSurfaceData object from the document try { surf = (MassSurfaceData)RvtDoc.GetElement(new Autodesk.Revit.DB.ElementId(SurfaceId.InternalId)); if (surf == null) { throw new Exception(); } } catch (Exception) { throw new Exception("Couldn't find a MassSurfaceData object with Id #: " + SurfaceId.ToString()); } //try to get the element id of the MassEnergyAnalyticalModel - we need this to pull faces from try { myEnergyModelId = surf.ReferenceElementId; if (myEnergyModelId == null) { throw new Exception(); } } catch (Exception) { throw new Exception("Couldn't find a MassEnergyAnalyticalModel object belonging to the Mass instance with Id #: " + surf.ReferenceElementId.ToString()); } //try to get the MassSurfaceData object from the document try { surf = (MassSurfaceData)RvtDoc.GetElement(new Autodesk.Revit.DB.ElementId(SurfaceId.InternalId)); if (surf == null) { throw new Exception(); } } catch (Exception) { throw new Exception("Couldn't find a MassSurfaceData object with Id #: " + SurfaceId.ToString()); } //get the smallest face Autodesk.Revit.DB.Face bigFace = GetLargestFace(RvtDoc, surf, myEnergyModelId); // Find the face normal at the center of the face BoundingBoxUV bbox = bigFace.GetBoundingBox(); // center of the face in the UV of the face Autodesk.Revit.DB.UV center = new Autodesk.Revit.DB.UV((bbox.Max.U - bbox.Min.U) / 2 + bbox.Min.U, (bbox.Max.V - bbox.Min.V) / 2 + bbox.Min.V); XYZ faceNormal = bigFace.ComputeNormal(center); XYZ normal = faceNormal.Normalize(); return(Autodesk.DesignScript.Geometry.Vector.ByCoordinates(normal.X, normal.Y, normal.Z, true)); }
/// <summary> /// Sets an exterior wall surface's energy parameters /// </summary> /// <param name="SurfaceId">The ElementId of the surface to modify. Get this from the AnalysisZones > CreateFrom* > SurfaceIds output list</param> /// <param name="glazingPercent">Percentage of glazed area. Should be a double between 0.0 - 1.0</param> /// <param name="shadingDepth">Shading Depth, specified as a double. We assume the double value represents a length using Dynamo's current length unit.</param> /// <param name="sillHeight">Target sill height, specified as a double. We assume the double value represents a length using Dynamo's current length unit.</param> /// <param name="ConstType">Conceptual Construction Type. Use the Conceptual Construction Types Dropdown node from our EnergySettings tab to specify a value.</param> /// <returns></returns> public static ElementId SetWallSurfaceParameters(ElementId SurfaceId, double glazingPercent = 0.4, double shadingDepth = 0.0, double sillHeight = 0.0, string ConstType = "default") { //local varaibles Document RvtDoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument.Document; MassSurfaceData surf = null; //try to get the MassSurfaceData object from the document try { surf = (MassSurfaceData)RvtDoc.GetElement(new Autodesk.Revit.DB.ElementId(SurfaceId.InternalId)); if (surf == null) { throw new Exception(); } } catch (Exception) { throw new Exception("Couldn't find a MassSurfaceData object with Id #: " + SurfaceId.ToString()); } //defense if (!(glazingPercent >= 0.0 && glazingPercent <= 1.0)) { throw new Exception("Glazing percentage must be between 0.0 and 1.0"); } if (shadingDepth < 0.0) { throw new Exception("Shading Depth must be positive"); } if (sillHeight < 0.0) { throw new Exception("Sill Height must be positive"); } try { //start a transaction task TransactionManager.Instance.EnsureInTransaction(RvtDoc); //change the 'Values' param to 1 - by surface var val = surf.get_Parameter("Values"); if (val != null) { val.Set(1); } //set target sill height surf.SillHeight = sillHeight * UnitConverter.DynamoToHostFactor; //set glazing percentage surf.PercentageGlazing = glazingPercent; //set shading if positive if (shadingDepth > 0) { surf.IsGlazingShaded = true; surf.ShadeDepth = shadingDepth * UnitConverter.DynamoToHostFactor; } else { surf.IsGlazingShaded = false; surf.ShadeDepth = 0; } //set conceptual construction if not empty if (!string.IsNullOrEmpty(ConstType) && ConstType != "default") { Autodesk.Revit.DB.ElementId myTypeId = getConceptualConstructionIdFromName(RvtDoc, ConstType); if (myTypeId != null) { surf.IsConceptualConstructionByEnergyData = false; surf.ConceptualConstructionId = myTypeId; } } //done with transaction task TransactionManager.Instance.TransactionTaskDone(); } catch (Exception) { throw new Exception("Something went wrong when trying to set the parameters on surface # " + SurfaceId.ToString()); } //return the surface ID so the surface can be used downstream return(SurfaceId); }