Returning the Component Assembly Occurrence of a Datum CSYS Feature

Hello,

I am attempting to gather the first datum feature's CSYS of all the components in an assembly.

I can successfully find the datum feature's CSYS if I input the ChildComponent.Prototype.OwningPart, however, the datum's position is relative to the part itself, not to the RootComponent.

When I use UI.SelectionManager.SelectTaggedObject to select the datum feature's CSYS from the assembly's point of view, I see that the datum feature's OwningPart is the RootComponent's part (which is what I want). This selected CSYS has the correct offsets, relative to the owning assembly.

How do I scan all of the features of the RootComponent itself (including the children component features)? That way I can assess the correct datum csys feature based on its owning component.

RootComponent.Prototype.OwningPart only reveals the features of the RootComponent itself, and not the children component features.

There's quite a bit of code involved in what I'm doing, so I can't post a journal script very easily. But I can post snippets of code as requested.

I appreciate any tips or suggestions.

Thanks.

If you have a reference to a component and a prototype object in the component part file, you can use the .FindOccurrence method to get the assembly occurrence of the prototype.

Something like:
occCsys = childComponent.FindOccurrence(protoCsys)

While looking for an example of FindOccurrence, I ran across this thread, which looks to be an earlier conversation we had on a related (same?) topic.

https://nxjournaling.com/content/get-owning-component-user-selected-datu...

In one of my replies, I caution against accessing features outside of the current work part. You CAN access features in other parts, but they must be fully loaded to do so. I don't want to make it sound like it is impossible to access features of other parts, you just need to be careful.

Oh wow I forgot about that post. Yeah, the code got popular so I am working to automate the solution and skip user selection, which produced the hiccup I mentioned above. I'll try FindOccurrence.

I am also ensuring the parts are fully loaded before I scan their features.

So the below snippets are in C#:

I convert the child component into a part:
indPart = (Part)indComp.Prototype.OwningPart;

I find the datum feature using:
foreach (object datum in searchPart.Features)

Then I try to convert the datum into a prototype using:
indPartDatumProto = (NXObject)indPartDatum.Prototype;

Finally I find try to find the occurrence:
indPartDatumOcc = (DatumCsys)indComp.FindOccurrence(indPartDatumProto);

However, since indPart is not an occurrence, indPartDatumProto is null. How do I search the feature collection of a component occurrence? That way I can return an occurrence datum prototype.

I'm assuming that "searchPart" is the same as "indPart"?

Note that features always belong to the owning part, the feature itself does not have an occurrence in the assembly, only the geometry it creates can have an occurrence. If you have a reference to a datum plane feature, get the actual datum plane object from the feature (myDatumPlaneFeature.DatumPlane) and look for its occurrence. Also note that if the datum plane is not included in the component's currently used ref set, it will probably return nothing.

You are correct that the two parts are the same. I have a method that pulls the the csys from the datum feature. parentPart is indPart in this case. Unfortunately, the CSYS found is still not an occurrence and does not have a prototype for me to reference.

public static CartesianCoordinateSystem FetchCoordinateSystem(DatumCsys datum, Part parentPart)
{
CartesianCoordinateSystem returnCsys = default;

DatumCsysBuilder datumBuilder = parentPart.Features.CreateDatumCsysBuilder(datum);
TaggedObject[] datumObjects = datumBuilder.GetCommittedObjects();

foreach (TaggedObject datObj in datumObjects)
{
if (datObj is CartesianCoordinateSystem csys)
{
returnCsys = csys;
break;
}
}
datumBuilder.Destroy();

return returnCsys;
}

As an alternative, I found that the SNAP documentation goes over cycling over solid bodies in an assembly using ufs.Obj.CycleAll(), I'm going to tweak it for CSYS objects to see if that will work that way.

The csys returned from your code will be the prototype csys. There might not be an occurrence csys in the assembly; make sure the datum csys objects are included in the current component ref set.

Alternately, your idea of using one of the cycling functions should also work, but will be a bit more work on your end. The cycling function will find all the csys objects in the assembly. You'll need to check each one to see if .IsOccurrence = true and if so, which component it comes from. If you have multiple of the same component in your assembly, you'll then need to determine which instance it belongs to.

Well, at least I know how to cycle through objects in the assembly. I got the cycling part working.

I was trying to fetch the prototype of the prototype, it seems, and that's why it returned null. You are correct in that the CSYS I fetched is a prototype. I used FindOccurrence to get the correct CSYS and that made everything work! Thanks again, I appreciate your patience and aid.

Glad to hear that you got it working, happy coding!