Before leaving for the weekend, let me highlight some recent additions to RevitLookup by Håvard Leding of Symetri:
- Three new RevitLookup commands
- About "Snoop Pick Face..."
- About "Pick Linked Element..."
- Running in a family document
I added and tested the new commands in RevitLookup release 2019.0.0.6.
Below is the description and some additional background information in Håvard's own words.
Many thanks to Håvard for implementing and sharing this!
Three New RevitLookup Commands
This is perhaps something of interest to someone.
Three very simple additions:
The first one really helped when debugging stable references on joined solid geometry in families.
Just the picked Reference
passed into the Object
form.
If I pass the GeometryObject
(the face), it will not retrieve a reference, presumably because GeometryObjectFromReference
doesn't calculate references.
If of any use, the commands are attached here.
Here is the code to generate the additional ribbon entries:
optionsBtn.AddPushButton( new PushButtonData( "Snoop Pick Face...", "Snoop Pick Face...", ExecutingAssemblyPath, "RevitLookup.CmdSnoopModScopePickSurface" ) ); optionsBtn.AddPushButton( new PushButtonData( "Snoop Pick Edge...", "Snoop Pick Edge...", ExecutingAssemblyPath, "RevitLookup.CmdSnoopModScopePickEdge" ) ); optionsBtn.AddPushButton( new PushButtonData( "Snoop Pick Linked Element...", "Snoop Linked Element...", ExecutingAssemblyPath, "RevitLookup.CmdSnoopModScopeLinkedElement" ) );
About "Snoop Pick Face..."
Using Autodesk.Revit.UI.Selection.ObjectType.Face...
gets you a reference to a face.
But if you use this instead...
Face face = cmdData.Application.ActiveUIDocument .Document.GetElement( refElem ) .GetGeometryObjectFromReference( refElem ) as Face;
...then Face.Reference
will be null.
Such a reference is needed when placing face-based families or dimensions, for example.
But it does get you a stable reference to the face:
string stableRef = refElem
.ConvertToStableRepresentation( uidoc.Document );
Which you can use to find the same face using Element.get_Geometry
.
Where Options
calculate the references.
And that face (really the same face) will have a usable reference.
Using Lookup, I found this stableRef
inside a GeomCombination
.
And so, I knew I had to include GeomCombination
in my FilteredElementCollector
.
Perhaps this could be an improvement on GetGeometryObjectFromReference
?
An overload to calcuate references if possible.
GetGeometryObjectFromReference(
Reference,
bool
CalculatedReference )
.
The new pick options helped guide me to my target face.
About "Pick Linked Element..."
"Snoop Pick Linked Element..." I haven't had use for yet.
I suspect I will use it quite a bit when debugging interaction with linked elements.
Seems to me you could have used "Pick Linked Element..." yourself in your latest discussion
on retrieving linked IfcZone
elements using Python.
Running in a Family Document
In my case, the code is running in a family document, not a project.
I get all the solids I need first, knowing that somewhere inside, there is the face I first picked.
List<Solid> solidsInFamily = new List<Solid>(); IList<Type> geomTypes = new List<Type>() { typeof( GenericForm ), typeof( GeomCombination ) }; ElementMulticlassFilter emcf = new ElementMulticlassFilter( geomTypes ); FilteredElementCollector colForms = new FilteredElementCollector( doc ) .WherePasses( emcf ); Options opt = new Options(); opt.ComputeReferences = true; foreach( CombinableElement combinable in colForms ) { if( combinable is GenericForm && !( combinable as GenericForm ).IsSolid ) continue; GeometryElement geomElem = combinable.get_Geometry( opt ); List<Solid> solids = Utils.GetElementSolids( geomElem ); solidsInFamily.AddRange( solids ); }
Then, using the stable reference from "Pick Face", iterate the solids until I find the face I'm looking for:
foreach( Solid solid in solids ) { foreach( Face face in solid.Faces ) { string stable = face.Reference.ConvertToStableRepresentation( doc ); if( stable == stableRef ) { return face as PlanarFace; } } }
Perhaps there is another, simpler, way of getting (picking) a face which has a reference?
But if I do this, passing the picked face, not the reference:
Then the Face
has no reference:
Which more or less prevents any interaction with it, such as placing dimensions, alignments or face-based families.
Enjoy!