Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Retrieve family instance position

18 REPLIES 18
Reply
Message 1 of 19
pmeigneux
8460 Views, 18 Replies

Retrieve family instance position

Hello,

 

We currently use the CustomExporter function to export the geometry of our Revit model.

 

In order to decrease the size of our extraction, we would like to make every extraction of family instances unique.

 

To do this, we use the FM.GetTransform() function.

[FamilyInstance FM = El as FamilyInstance in the function OnElementBegin(ElementId elementId)]

 

However, we didn’t find how we can transform the points position (node.GetPoints()) inside the function: OnPolymesh (PolymeshTopology node),

 

Thanks for your support,

 

Philippe

18 REPLIES 18
Message 2 of 19
jeremytammik
in reply to: pmeigneux

Dear Philippe,

 

Thank you for your query.

 

Have you looked at the various examples listed in The Building Coder topic group on the custom exporter?

 

http://thebuildingcoder.typepad.com/blog/about-the-author.html#5.1

 

The Custom Exporter to XML lists all accessible info:

 

http://thebuildingcoder.typepad.com/blog/2013/07/graphics-pipeline-custom-exporter.html#4

 

That should definitely provide all you need.

 

I hope this helps.

 

Best regards,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 3 of 19
pmeigneux
in reply to: jeremytammik

Hello,

 

Thanks for your response.

 

Unfortunately, we have already looked at this Building Coder Topic.

 

Our main concern is about the position of the instance. We search to retrieve all points coordinates of the objects in link with the instance coordinate system.

 

Currently, all information that we retrieve with this function, refers to the file coordinate system.

 

Regards,

 

Philippe

Message 4 of 19
pmeigneux
in reply to: pmeigneux

For example, take the case of a RVT project with 200 instances of the same windows family.

 

We would like to retrieve two types of information:

 

  • First, we want to extract the relative position of the geometry (points) window in the instance coordinate system.
  • Second, we want to obtain the 200 transformation matrix in order to know all the windows position in the project.

By this way, we want to decrease the size of our extraction process.

 

Regards,

 

Philippe

Message 5 of 19
FAIR59
in reply to: pmeigneux

To get the geometrypoints relative to the  instance:

 

FamilyInstance _instance;

Transform _T = _instance.GetTransform();

 

XYZ _geometrypoint;

 

XYZ _point_relative = _T.Inverse.OfPoint(_geometrypoint);

 

 

 

 

For your method to work, you'd have to check that the instances are geometrical identical.

 

In general even FamilyInstances of the same FamilySymbol need not be identical !!

  • Instance Parameters can drive the geometry.
  • FamilyInstances of category Doors / Windows  can react to the thickness of the host Wall.
  • FamilyInstances can be cut by other Elements in the model. 

 

Message 6 of 19
pmeigneux
in reply to: FAIR59

Hello,

 

Thank for your response.

 

We have two more questions to solve our query.

 

  • How can we determine if instances are geometrical identical? For example, what’s the approach to determine if a FamilyInstances is cut by another element in the model?
  • Is the relative position of the FamilySymbol the same for every project?

Regards,

 

Philippe

Message 7 of 19
jeremytammik
in reply to: pmeigneux

Dear Philippe,

 

Thank you for your update and glad to see that things are getting clearer.

 

  1. Determine identical geometry? Difficult. You can check the solids, number of faces, volume, surface area, etc. For a more precise result, you could generate a solid for each of the two instances you are comparing and perform a Boolean operation on them. Heavy...

 

  1. Yes, the family symbol insertion point is the coordinate system origin in the family definition, afaik, and would thus be identical for all instances.

 

I hope this helps.

 

Best regards,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 8 of 19
BobbyC.Jones
in reply to: jeremytammik

From reading the docs it sounds like you can simply test for the existence of a GeometryInstance at the top level of the family instance.  If it's not there, then the the family instance has been modified from the symbol geometry.  This is the check I mentioned in this thread, How to get a Solids location in the project, and is demonstrated in some of Jeremy's code which he provides a link to in that same thread.

 

 

Excerpt from the Remarks section of GeometryInstance class:

Note that not all Family instances will include GeometryInstances. When Revit needs to make a unique copy of the family geometry for a given instance (because of the effect of local joins, intersections, and other factors related to the instance placement) no GeometryInstance will be encountered; instead the Solid geometry will be found at the top level of the hierarchy.

--
Bobby C. Jones
Message 9 of 19
pmeigneux
in reply to: BobbyC.Jones

Thanks again for your response.

 

I would like to re-update this post, because I have a few remaining questions:

 

1/ About the exact position of Family Instance:

 

I use GetTransform on InstanceFamily to obtain the position in the absolute coordinate system.

After, I use PolymeshTopology on InstanceFamily to have the tesselate geometry on each face of the solide.

 

My aim is to obtain for all points of the geometry,  the coordinates in the instance coordinate system.

According to your advice, I try to used the Invert Matrix to do the point transformation from the absolute coordinate system to instance coordinate system.

However, it didn't work. For example, this operation doesn't take in consideration the translation operation.

 

 

 

2/ About determine if instances are geometrical identical:

 

We advance on that point too but we didn't arrive to make the difference if an InstanceFamily is cut by another element or if it change according to his host (for example a door hosted by a wall)

This is my question:

 

How can we obtain the list of every modification possible on each InstanceFamily? And how can we track them?

 

 

Thanks again for your support,

 

Philippe.

Message 10 of 19
GOverfield
in reply to: pmeigneux

First, you need to ensure that you are using the Autodesk.Revit.DB namespace.  Assuming you are already, hopefully you're familiar with the XYZ class.  This is used to find or define location points within a document.  To extend on that, all FamilyInstances have a Location property, which is an XYZ.  My company created a whole file called FamilyUtils.cs to help us deal with FamilyInstances. 

 

The long story short is this:  I would recommend creating a function to grab your FamilyInstance locations.  Ours looks like this:

public static XYZ GetFamLocation(FamilyInstance pFam)
{
    return ((LocationPoint)pFam?.Location)?.Point;
}

 

As far as moving FammilyInstances goes:

FamilyInstance pFam;
//Grab your desired FI

using (Transaction pTrans = new Transaction(pDoc, "Move Object")
{
    pTrans.Start();
    XYZ fVector;
    //Initialize the vector to determine by what magnitude you want to move the FI
    pFam.Location.Move(fVector);
    pTrans.Commit();
}

*You must ALWAYS be in a Transaction if you're altering the contents of your document.

 

As far as comparing locations of Elements/FamilyInstances:

FamilyInstance pFam1, pFam2;
XYZ fFam1, fFam2;

fFam1 = GetFamLocation(pFam1);
fFam2 = GetFamLocation(pFam2);

bool bAreSameLocation = fFam1.IsAlmostEqualTo(fFam2);

 

As you can see, this also null coalesces the location so you won't get an error if the FamilyInstance is an invalid object.  Hope that helps.  Let me know if you need more help with this or anything.

Message 11 of 19
jeremytammik
in reply to: GOverfield

Thank you!

 

Neat use of coalescion!

 

I added your method to The Building Coder samples:

 

https://github.com/jeremytammik/the_building_coder_samples/commit/da15d0bb03b05019c8ab26022a6efbce42...

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 12 of 19

XYZ method IsAlmostEqualTo(XYZ source) throws a ArgumentNullException when source is null, and the Location is not always a LocationPoint (LocationCurve is also a Location).

 

Here is a safer TryGet pattern version:

 

 

public bool TryGetLocationPoint(FamilyInstance instance, out XYZ point)
{
    if (instance?.Location is LocationPoint location)
    {
        point = location.Point;

        return true;
    }

    point = null;

    return false;
}

 

 

 

 

 

 

Message 13 of 19

Thank you for the improvement.

 

Question:

 

If you know that the element it a family instance, is the Location property then not guaranteed to be a LocationPoint?

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 14 of 19
Revitalizer
in reply to: jeremytammik

Hi Jeremy,

 

there a line-based families, too, having a LocationCurve.

 

 

Rudi




Rudolf Honke
Software Developer
Mensch und Maschine





Message 15 of 19
jeremytammik
in reply to: Revitalizer

Hi Rudi,

 

Thank you!

 

Oh!

 

Then this is probably better:

 

GetElementLocation in The Building Coder samples Util.cs:

 

https://github.com/jeremytammik/the_building_coder_samples/blob/master/BuildingCoder/BuildingCoder/U...

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 16 of 19
pmeigneux
in reply to: GOverfield

Hello,

 

Thanks for your response.

 

Unfortunately, I am looking for the transformation matrix for each geometric point.

 

With your example, I only obtain the XYZ coordinate. This is not enought for us.

 

Thanks,

 

Philippe

Message 17 of 19
mastjaso
in reply to: jeremytammik

Hi I know this is old but I just wanted to follow up on point 2 in case anyone else comes across this:

 


@Anonymous wrote:

 

 

  1. Yes, the family symbol insertion point is the coordinate system origin in the family definition, afaik, and would thus be identical for all instances.

 



I believe this is not necessarily true. Inside a family reference planes have the option "Define Origin" and the intersection of the vertical and horizontal reference planes with this option checked is the family instance's Insertion Point but is called the "Origin" for the Revit user. 

 

By default the centre left/right, and centre front/back reference planes are created and pinned with their "Define Origin" properties being checked and their intersection at the internal Origin. However if you unpin these planes and move them the insertion point stays at their intersection but the internal origin remains where it was. You can double check this by importing a CAD file that has lines drawn at (0,0) like this:

FamilyInsertionAndOrigin.png

 

 

Message 18 of 19
mastjaso
in reply to: mastjaso

Whoops, forgot to add that if you want to actually get a FamilyInstance's real origin point (as opposed to insertion point) in your model coordinates you'd call FamilyInstance.GetTotalTransform().Origin. You can see the difference quickly sketched out here using dynamo:

FamilyInsertionAndOriginInModel.png

 

 

Message 19 of 19
RPTHOMAS108
in reply to: pmeigneux

If as you say it is the same window family why not check position is same and then compare the parameters (since they drive geometry)?

 

.LocationPoint has an orientation

For line based families the 3D orientation (as a key to compare) can be found from the normalised vector of one end subtracted from the other (if ends are always subtracted in the same order).

.HandFlipped & .FacingFlipped properties will determine if asymmetrical geometry driven by parameters is reversed.

 

All of the above items can be compared to find unique matches rather than generating geometrical points for comparison.

 

i.e. how many geometry nodes to compare versus the parameters, plus geometrical nodes will have rounding inequality issues.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Rail Community