ReferenceKeyManager Produces unusable Key/KeyContext-Pairs

ReferenceKeyManager Produces unusable Key/KeyContext-Pairs

Bert_Bimmel
Advocate Advocate
723 Views
8 Replies
Message 1 of 9

ReferenceKeyManager Produces unusable Key/KeyContext-Pairs

Bert_Bimmel
Advocate
Advocate

Shouldn't Inventor complain, if I try to create a (B-Rep) - ReferenceKey from one document providing the KeyContext that has been created within another document? Especially if the first document is a PartDocument, and the other Document is an AssemblyDocument?

Actually, it does not, but creates combinations of ReferenceKeys and KeyContexts which are unusable instead!

 

Yes, it was my fault to mix it up, but it took me quit a long time to figure out why my Keys won't Bind to any object, respectively why the Contexts could not be loaded from the arrays.

Some useful error messages upon creation would have saved a lot of investigation.

 

0 Likes
724 Views
8 Replies
Replies (8)
Message 2 of 9

Bert_Bimmel
Advocate
Advocate

Some more investigation later: No, It was'nt entirely my fault:

 

take a look at this related post of mine:
https://forums.autodesk.com/t5/inventor-programming-ilogic/how-to-obtain-original-face-from-a-facepr...

Pick a Face on an edited PartOccurrence inside an Assembly, ask for the NativeObject of that Face (which Inventor considers beeing a FaceProxy). As stated above, Inventor considers this Face's SurfaceBody as Object inside the Assemblie's Definition:

Bert_Bimmel_0-1715071746076.png

Now, let the Assemblie's ReferenceKeyManger produce a Key + KeyContext for that FaceObject.
The Key + KeyContext-couple is unable to bind back to any object, neither the Face, nor the FaceProxy (which, as also already stated above, are basically the same thing).

0 Likes
Message 3 of 9

WCrihfield
Mentor
Mentor

Hi @Bert_Bimmel.  I know that all this assembly proxy stuff can be pretty complicated to understand in our heads a lot of the time.  What I usually try to keep in mind is that, nothing in an assembly is 'real', except maybe the welds in a weldment type assembly, and maybe the sketches and work features that were created directly within the assembly, and not while editing any component.  Everything else is just a proxy, simply because this is an assembly (just a place to bring 'other' stuff together').  This is why assemblies lack a lot of the tools that are available in parts, because we were essentially not really supposed to be 'creating' new 'real' stuff within assemblies...just assembling or modifying 'other' stuff that already exists outside of the assembly.

 

Anyways, in another recent forum post, the original poster was working with transient BRep copy of a sheet metal part, and wanted to be able to identify faces of the original part on the new transient body.  He was also using that Face.AssociativeID property.  It seems that property was visible in the 2023 version of Inventor, but not in 2022 or in 2024, so I never saw its 'official' documentation until then.  But an old 2013 post, which involved someone who worked for Autodesk for a while included an example of code using that property.  It turns out that it was primarily designed for use with 'transient BRep' stuff.  So, it was perfect for what he was using it for.  But since it was relatively undocumented, he wanted to make sure it was OK & stable to use.  Well, an Autodesk employee chimed in, and confirmed that it was good to use in those special situations, and that it will likely be un-hidden in a future release of Inventor again.

 

Just keep in mind that the Face.AssociativeID property may not have anything at all to do with the ReferenceKeys system.  And, I do not know if the ReferenceKeys system plays well with bodies/faces that were created using the transient BRep system.  We do know that the ReferenceKeys system works well with 'regular / normal' faces in parts.  And it seems like the Face.AssociativeID property is good for figuring out a connection between an 'original' Face, and the copy of that Face on a transient BRep copy of it.  So, in the case where we are working within an assembly, where proxies are involved, plus we are working with transient BRep stuff, we may need to utilize both system.  Not sure.  I do not really have the need to dive that deep into situations like that for my work.  I have just read a lot of these very similar forum topics over the years, and have seen a lot of attempts / solutions for various related problems.

 

Edit:  Just adding one additional note, about the ProxyObject.NativeObject property...

This property does not always return a 'real' or 'original' object.  (The value of FaceProxy.NativeObject may not always be a regular Face object.)  This is because, if the real part is down 3 level deep (within a sub assembly of a sub assembly), then the face you get directly within the 'context' (3D model space) of the main assembly will be a FaceProxy.  Then the FaceProxy.NativeObject of that will still be a FaceProxy, but in the context of that first level sub assembly.  Then that FaceProxy.NativeObject will still be a FaceProxy, but in the context of the second level sub assembly.  Then finally the FaceProxy.NativeObject of that will be the real / original Face object, because that will finally be in the context of the actual part.  The same goes for using the ComponentOccurrence.CreateGeometryProxy method.  If used on that 3rd level assembly component, it will return a FaceProxy that is still in the context of the second level sub assembly, not yet in the context of the main assembly.  Then you have to use the ComponentOccurrence representing that second level sub assembly, and use its CreateGeometryProxy method to get a reference to the FaceProxy that exists within the context of the first level sub assembly.  Then again, use the ComponentOccurrence object representing that first level sub assembly, and use its CreateGeometryProxy method to finally get a reference to the FaceProxy object that exists in the context of the main assembly...where you can actually use it for things like measurements and constraints.  Just pointing out that proxies can have multiple levels to them, making the whole process that much more complex, at times.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 4 of 9

Bert_Bimmel
Advocate
Advocate

Hi Wesley Crihfield

 

Thanx for your very elaborate explanation!

I agree, that what you have explained about the proxy of a proxy of a proxy, when dealing on a Face whose containing part is buried deep down in my assembly-tree would make sense.

But other than I would have expected (even before I have read your post), the NativeObject-property seems to lead to the original face directly, skipping all the intermediate proxies.

Instead, its "ContainingOccurrence" (which also directly leads to the containing part) is exposed as an OccurrenceProxy with the entire OccurrencePath attached:

Bert_Bimmel_0-1715324029118.png

 

 

IMHO, the shortcut to the "Surface" (nice pun btw. 😄 ) might be handy sometimes, but it should rather be a bonus-property, whereas the "NativeObject"-Property should rather lead to the next-Level's FaceProxy if applicable. Plus, they should offer a “ContainingOccurrence”- and a “ContainingLeafOccurrence”-property, where the first one delivers the next-level subassembly, and the second one is the shortcut to the containing part. That would make it much more stringent.

(Note: When creating a constraint via GUI, the entire process of creating a proxy of a proxy of a proxy takes place automagically in the background)

 

Now about transient B-Reps: I'd say they're not really that "transient":

E.g.: When I create a very simple Assembly, containing nothing else than a single occurrence, of a very complex part, the assemblie's FileSize is very moderate:

Bert_Bimmel_1-1715324029123.png

 

But as soon as I drill a hole into that complex part in the Assemblie’s context, the file size explodes:

Bert_Bimmel_2-1715324029133.png

 

That is, because the Assembly does now contain an entire (associative) copy of the surface-body from the part. It’s pretty much like an associative Body copy in another part-document or a derived part, which both do also contain (associative) copies of the original body:

Bert_Bimmel_3-1715324029135.png

 

(The Part is that much bigger, because it contains two copies of the embedded sab-file: one inside PmBRepSegment plus another one in PmDCSegment)

So, the difference between Assembly and Part is becoming somewhat blurry here.

 

Anyway, the solution to the problem of getting hold of the original face of an edited body proxy that has been proposed by Michael.Navara in my related post (see link in my post above), seemed to work nicely at a first glimpse, but on a deeper (but still shallow) view i’d say it’s unlikely to work reliably when the lid and the bottom of a simple extruded-circle-can both have the identical AssociativeFaceID of “0”:

Bert_Bimmel_4-1715324029139.png

 

Or, what happens if the original face has been cut in two when beeing editet in the assembly context?

Bert_Bimmel_5-1715324029142.png

 

I haven’t yet tried to figure out what happen’s in this case, but my intuition says, it’ll totally bust the AssocFaceID-approach. 😞

Anyway, that AsscoiativeFaceID-Stuff seems pretty “beta” to me – especially after having read your comments on that.

So, the conclusion would be: there is no satisfactory solution to the whole thing, is there?

0 Likes
Message 5 of 9

WCrihfield
Mentor
Mentor

Hi @Bert_Bimmel.  Thank you too, for the detailed response and explanations.

There is a lot to cover here, in an attempt to respond to all of that, and not sure I will get to it today, because I have lot of stuff going on at work.  As I have mentioned before, I am honestly not the most experienced in using the ReferenceKey / KeyContext system myself.  I have used the NamedEntities system (in parts), and custom solutions which work similarly to that system for use in assemblies for years (not a lot on the assembly side yet though).  Both of those systems create a specifically named AttributeSet on the object, then a specifically named Attribute within that set, with a String type value, and specify the entities name as its value.  Then use either the NamedEntities iLogic tool, or the AttributeManager tools for finding them later.  Those seemingly simpler systems have been sufficient for my needs for several years.  I do not really recall having to identify FaceProxy objects in the context of an assembly that have been modified within the assembly, from the named part face by code on that many occasions.  I have definitely done that process a lot of times where no assembly level modifications had been made though.  I even developed multiple of my own recursive Functions for either stepping up to the top level, or down to the 'original' from proxy objects at various levels within large assemblies, and some custom Sub routines for other proxy related tasks, and put them into one external iLogic resource, for referencing from other rules.

 

As for the Face.AssociativeID property.  I do not have any experience with that one either.  I have just seen it being used in multiple forum discussions lately, and the one which the Autodesk employee looked into it for us.  In the old 2013 post, and in the newer posts, the theme seems to be that this property is not used the same way that the ReferenceKey or named entity systems are used, but seems to have been around for a pretty long time, and seems to have been created primarily for use in transient BRep copy type situations.  So, can only restate some of the stuff I have seen in those other posts as far as that goes.  But I do not think of assembly proxy stuff as being the same as transient BRep stuff.  Proxy stuff is real enough (not transient), just difficult to explain, and it can be difficult to determine how much another person on the forums may already know about these subjects, so sometimes I may attempt to explain too much, when it is not needed.  It sounds like you already had a pretty good grasp on a lot of this stuff.

 

On another related note, you may already be aware of this one also, so I apologize if you already know about it, but when we use the CommandManager.Pick function to select things in an assembly that we want to analyze by code, that can make a big difference, versus obtaining the object through purely code means, and a lot of folks I have encountered did not realize it.  If the main assembly document is visible on our screen, and we are not in edit mode of any of its components, and we use that Pick method to select the face of a component, we always get the proxy object that is in the context (3D model space) of the main assembly, no matter how many levels deep that component may have been within the assembly's structure.  In situations like that, I always had to dig down 'n' number of levels to get access to the part face that was actually in the context of the part document itself.  Similarly, if I obtained a reference to the part's face (in the context of the part document), then wanted to get its proxy that was in the context of the main assembly, when it was a couple levels deep within that assembly, I always had to step up multiple steps to get to proxy that I needed for things like measurements or constraints that I wanted to get / create within the context of the main assembly itself.  Context changes of an object that seems like it should be the same object, can be difficult to account for, or track.  It seems to me like the only tool I have ever seen in Inventor's API that may be able to jump multiple proxy levels is the AssemblyComponentDefinition.AdjustProxyContext method, but I do not believe I have done much testing with that specific method yet myself, but I do want to when time permits.  If for no other reason than the fun of researching the subject further and learning something new & useful.  So, I can not explain what you seem to be showing within a VBA editor Watches dialog.  Some of the words in the image are in a language that I can not read.  Maybe stepping back through all those additional 'parent' steps (SurfaceBody, ComponentDefinition, Document) has an effect of crossing multiple proxy levels too...not sure there.  I know that in multiple of my own working iLogic rules that deal with multi-level proxies so far, I have not encountered any built-in 'shortcut' to jump multiple proxy levels, while accomplishing what I needed to accomplish (other than pushing the task out to one of my functions).

I very much agree that a built-in tool for that type of task (skipping directly to the top or bottom) would be of great interest and use to a lot of folks.

Good luck with your entity ID system investigation.  I hope you are able to find the answers / solutions you are looking for.  Wish I could help more.  It has definitely been an interesting discussion.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 6 of 9

Bert_Bimmel
Advocate
Advocate

You are aware, that the AttributeSets which iLogic attaches to a B-Rep-Entity for storing that Entitie's "Name"  are bound to that particular Entity by a common ReferenceKey/KeyContext-Set, which is stored inside the FBAttributeSegment, so that Inventor can assign Name-Attributes and B-RepEntities to each other beyond edits?

 ;-D

 

0 Likes
Message 7 of 9

WCrihfield
Mentor
Mentor

Hi @Bert_Bimmel.  Actually, no.  I am not familiar with the "PmBRepSegment", "PmDCSegment", & "FBAttributeSegment" terms, or the "sab-file" you mentioned in your previous post.  I would certainly like to hear more about them though, if you have the time and understanding about them.  I am always very interested in learning new things.  That's part of the reason I do what I do here.  Not only to help others, but to learn new stuff from others, and improve my skills in various other areas of Inventor automation.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 8 of 9

Bert_Bimmel
Advocate
Advocate

Hi Wesley,

Have you ever seen an Error Message saying something like "Error reading PmDCSegment" or similar when trying to open a broken File?

An Inventor file is organized in multiple segments, which are not directly exposed through the API. Their names are more or less self explanatory. An ipt file for instance contains...

PmBrowserSegment: This contains all information about the browser tree with the nodes for the part's features, sketches etc.

PmBRepSegment: This contains the anlytical model, i.e. the surface bodies, which in turn are basically embedded sab-files: The modeling kernel of inventor originates from the ACIS-modeling kernel, which provides two file formats: sat (standard acis text, which is an ascii-format), which you probably know pretty well as 3D-neutral format beside STEP, and sab (standard acis binary), which is very uncommon. There are means to import these into Inventor via API, but there's no support in the common file-dialog. 

PmDCSegment: I can't really tell what DC stands for, i'd just guess ist something like design components or something similar. Whereas the BrowserSegment contains only the browser-structure with their nodes, this segment contains the real things, i.e. information about workplanes, sketches and their content (lines, constraints etc.), modeling features etc...

PmGraphicsSegment: This segment contains one or more triangulations of the analytical model as input for the GPU to draw your model onto your screen. (this can contain mutliple representations with different resolutions)

PmResultSegment: This one contains information about the MassProperties for instance

PmAppSegment: This one contains Information about DocumentSettings like units of measure, Styles etc.

FBAttributeSegment: This one contains everything about Attributes.

NBNoteBookSegment: When you make use of the notes function in Inventor, the information is stored here,

DesignViewSegment: Everything about visibilities and stuff (more important for Assemblies)

And in case you're working with routed systems there may occur some EESceneSegments and EEDataSegments.

 

In iam-files there are basically the same segments, but instead of "Pm" they're prefixed with "Am"
idw and ipn files contain different segments, but the container-format is  the same.

 

Message 9 of 9

WCrihfield
Mentor
Mentor

Hi @Bert_Bimmel.  Thank you for taking the time to explanation these terms, and your observations about them so far to me.  No, I do not recall seeing any of those terms mentioned within error messages, but that may just be a case of not remembering the parts of error messages that did not seem helpful at the time, and I will certainly be looking out for them now.  I have taken long looks into some of the other odd stuff I have seen within the 'More Info' tab of error messages before, which did lead to new discoveries in the past, so maybe this will also lead to more discoveries in the future.  I was aware that we could directly export SurfaceBody objects using their DataIO property and its methods, with 10 different options for different variations of ACIS SAT or ACIS SAB file types.  Some with 'TransientKeys', some with 'ProceduralToNURBS', some with both.  I do not recall needing to work with those file types directly before myself, but I did read about the ACIS core being used by multiple CAD entities again a while back.  I know I have encountered SAT files before, but I to not recall encountering SAB files before.  Needing to store this type of data behind the scenes in a slightly different way (segment), while storing other types of data in other ways does make sense though.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes