In this post I want to show a method that allows to automatically dimension curtain walls in Revit, with the result as on an image above.
First let’s assume that our input data are: a curtain wall, a line specifying location of the future dimension line and a view. In order to create a new dimension line in Revit we use such code:
doc.Create.NewDimension(view,line,refArray);
Where “doc” is our Revit document, “view” a view where we want to draw the dimension, “line” dimension placement line and “refArray” a list references to all measured objects/lines.
To get result as above we need to find two kinds of references:
-the ones that point to side edges of the wall
-the ones that point to vertical grid lines
The first ones will be collected directly from the wall geometry. In order to do that we need to find a Geometry Object of our wall, like so:
Options options = this.Application.Create.NewGeometryOptions(); options.ComputeReferences = true; options.IncludeNonVisibleObjects = true;
Where”w” is the wall and “options” is a helper object containing parameters of the geometry extraction. It is important here to set it so it takes into account non visible objects and object references.
Next we iterate the geoElement to find solid objects. Then we check direction of all the solid’s faces (normal vector). If it is parallel to the direction of the dimension line we can add this face’s reference to the list. (refArray). It would look like that:
foreach(GeometryObject obj in geoElement){ Solid s = obj as Solid; if(s!=null) { foreach(Face f in s.Faces){ PlanarFace pf = f as PlanarFace; if(pf!=null) { XYZ faceNormal = pf.FaceNormal; if(isParallel(faceNormal,line.GetEndPoint(1)-line.GetEndPoint(0))) { refArray.Append(f.Reference); } } } } }
Now we are gonna collect references to the vertical grid lines of the wall. We can do it using such code:
ICollection gridIds = w.CurtainGrid.GetVGridLineIds();
The above function returns ids of the grid lines, not the objects themselves. Therefore we have to find them in the document (using the ids) and then query them for any line geometries. References to those lines are added again to the list. Like so:
foreach(ElementId gridId in gridIds) { CurtainGridLine gridLine = doc.GetElement(gridId) as CurtainGridLine; if(gridLine!=null) { GeometryElement gridGeo = gridLine.get_Geometry(options); foreach(GeometryObject obj in gridGeo) { Line l = obj as Line; if(l!=null) refArray.Append(l.Reference); } } }
Code for the entire function could look like this:
And this would be a Dynamo version, in Python:
curtainDim.dyn