/// <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);
        }
Example #2
0
        // 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);
        }
Example #5
0
        // 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);
        }