Project XYZ in world coordinates on geometry in nested familyinstance

Project XYZ in world coordinates on geometry in nested familyinstance

m.de.vriesTH5VM
Enthusiast Enthusiast
1,243 Views
2 Replies
Message 1 of 3

Project XYZ in world coordinates on geometry in nested familyinstance

m.de.vriesTH5VM
Enthusiast
Enthusiast

This should be easy to do but I cannot find the solution.

I need to test if a XYZ in world coordinates can be projected on a face of the 3D geometry of a familyinstance, and if so what the coordinates are relative to the low left corner of that face.

 

My code gets the GeometryInstance of the family (it does not make much difference if I use GetInstanceGeometry or GetSymbolGeometry for this). Then I filter out the Solids that meet certain conditions and from those I filter out the Faces that meet certain conditions.

I then use XYZ ocsXYZ  = FamilyInstance.GetTotalTransform().Inverse.OfPoint(worldXYZ); to get the world coordinate in the local coordinate system of the family.

I can then use Face.Project(ocsXYZ); to find if the point can be projected on the face and what the UV is of that projected point for the coordinates relative to the face origin (and from there I can correct it to be relative to the low left corner of the face).

 

This is a lazy method but it worked fine until recently, when a customer reported an error with this part of the code.  Even though the wcs point visibly should project on a face of that family instance, the code could not find one.

It turned out that the customer had the relevant 3D geometry in a nested family, and rotated and mirrored that instance.

The geometry instance has the 3D coordinates of the face relative to the definition of the family they are defined in. And the GetTotalTransform() only returns the transform for top level family to world coordinates.

There is a missing Transform here, or potentially many if the geometry is more deeply nested.

Using GetTransformedCopy() on the GeometryInstance will not work because the only transform I have is of the top level family instance, and it will not take into account the effect of the transforms of the nested instances.

 

I can of course open each family in an editor to find the transform of the nested elements, but that seems incredibly inefficient to me. 

 

Given that revit itself has no problem working with nested geomerty, no matter how the nested instances are transformed, there must be a better solution readily available. I hope that somebody knows and can give me a hint of where to look for it.

 

 

Thanks in advance,

Mark de Vries

ICN Development

0 Likes
Accepted solutions (1)
1,244 Views
2 Replies
Replies (2)
Message 2 of 3

jeremy_tammik
Alumni
Alumni
Accepted solution

You can take a look at ElementViewer, one of the very early Revit SDK samples, discussed by The Building Coder in blog post #13:

 

https://thebuildingcoder.typepad.com/blog/2008/09/geometry-viewer.html

 

It extracts all edges from a Revit element and displays them in a Windows form, including all the required nested transformations.

 

I assume that in your case, the GetTotalTransform is only returning the transform for one of the layers of the nested structure, and you need to iterate (or presumably recurse) through the entire hierarchy of nested families and concatenate all the transforms together for the final result. ElementViewer will show you how that can be achieved.

 

Here are some early blog posts dealing with nested family instance geometry:

 

 

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 3 of 3

m.de.vriesTH5VM
Enthusiast
Enthusiast

Hello Jeremy and thank you for your reply.

 

I was afraid that I would have to scan through the entire hierarchy of 3D geometry elements to find the nested Transforms. Because that is so inefficient I was hoping there was some API method that could help with this. After all, Revit needs to scan the definitions when it looks for the 3D geometry of an element so it would have been possible to also keep track of the local Transforms of those nested families. But probably that is more complicated than it sounds. It may be something to suggest to the API team though, a function method to get the 3D geometry as a nested hierarchy including the Transforms at every level (similar to what e.g. AutoCAD does for some of its selection functions where you can get the entire nesting and transformation hierarchy of the element you selected)

 

Thank you for the reply and the resources. I think I have already used some of it in another part of the project where I had to get a more accurate boundingbox of the visible 3D geometry, so I will be able to write a method that gives me the WCS transformed copy of every bit of 3D geometry in an object.

0 Likes