Hello
So I have a specific occurrence of a part in an assembly, and I have a surface in that part document identified by a reference key.
Ultimately I'm trying to create proxy geometry of these surfaces in the assembly from any occurrence, but the reference key can't be used from the context of the assembly with the `Occurrence.Definition.Document` object, which I think means I first need to find the surface using the reference key, within the part document itself.
But the `Occurrence.CreateProxyGeometry` method seems to need the surface of the `Definition.Document`.
How can I take the part document surface and find the same surface as it exists within the occurrence object? Is this possible? Am I otherwise able to use reference keys (or something else that operates similarly) in part documents to find matching entities in an occurrence?
Thanks
Solved! Go to Solution.
Hello
So I have a specific occurrence of a part in an assembly, and I have a surface in that part document identified by a reference key.
Ultimately I'm trying to create proxy geometry of these surfaces in the assembly from any occurrence, but the reference key can't be used from the context of the assembly with the `Occurrence.Definition.Document` object, which I think means I first need to find the surface using the reference key, within the part document itself.
But the `Occurrence.CreateProxyGeometry` method seems to need the surface of the `Definition.Document`.
How can I take the part document surface and find the same surface as it exists within the occurrence object? Is this possible? Am I otherwise able to use reference keys (or something else that operates similarly) in part documents to find matching entities in an occurrence?
Thanks
Solved! Go to Solution.
Solved by WCrihfield. Go to Solution.
Hi @meGVGMF. I have not used the ReferenceKey & ReferenceKeyManager system that much but I do know that it is document specific (only works within the scope of the one original document). The most common way to find part geometry from an assembly is by assigning names to the geometry while editing the part. But that 'assign name' system uses the Object.AttributeSets property to create a new specifically named AttributeSet & new specifically named Attribute on the Object, which can then be found through the Document.AttributeManager, so I suppose it is a bit similar in functionality. But when using the named entities route, there is a nice iLogic shortcut tool for working with them. Unfortunately though, that built-in system does not work directly in the assembly environment, so you would have to get the face from a component's referenced document, then use that component to get a reference to the proxy of that geometry within the 'parent' assembly's context (3d model space), then you can use that proxy at the assembly level. We can actually assign names directly to proxy geometry in the context of an assembly, but we just can't use the iLogic shortcut tools to do it that way, we would have to use our own tools, and different names for the AttributeSet &/or Attribute.
Wesley Crihfield
(Not an Autodesk Employee)
Hi @meGVGMF. I have not used the ReferenceKey & ReferenceKeyManager system that much but I do know that it is document specific (only works within the scope of the one original document). The most common way to find part geometry from an assembly is by assigning names to the geometry while editing the part. But that 'assign name' system uses the Object.AttributeSets property to create a new specifically named AttributeSet & new specifically named Attribute on the Object, which can then be found through the Document.AttributeManager, so I suppose it is a bit similar in functionality. But when using the named entities route, there is a nice iLogic shortcut tool for working with them. Unfortunately though, that built-in system does not work directly in the assembly environment, so you would have to get the face from a component's referenced document, then use that component to get a reference to the proxy of that geometry within the 'parent' assembly's context (3d model space), then you can use that proxy at the assembly level. We can actually assign names directly to proxy geometry in the context of an assembly, but we just can't use the iLogic shortcut tools to do it that way, we would have to use our own tools, and different names for the AttributeSet &/or Attribute.
Wesley Crihfield
(Not an Autodesk Employee)
Here is sample how to obtain RefKey and Context from part environment and bind them back in part and assembly.
Get RefKey and Context in part
Dim face As Face = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kPartFaceFilter, "Select face")
Dim part As PartDocument = face.Parent.Parent.Document
Logger.Debug(part.DisplayName)
Dim refKey As Byte() = {}
Dim ctxt As Integer = part.ReferenceKeyManager.CreateKeyContext()
face.GetReferenceKey(refKey, ctxt)
Logger.Debug("RefKey:" & vbCrLf & String.Join(", ", refKey))
logger.Debug("Context: " & ctxt)
Get face in part
Dim refKey As Byte() = {1, 4, 5, ... see sample for full value ..., 0 }
Dim ctxt As Integer = 1
Dim part As PartDocument = ThisDoc.Document
Dim face As Face = part.ReferenceKeyManager.BindKeyToObject(refKey, ctxt)
part.SelectSet.Select(face)
Get faceProxy in assembly
Dim refKey As Byte() = {1, 4, 5, ... See sample for full value ..., 0 }
Dim ctxt As Integer = 1
Dim occIndex As Integer = 1
'Get part froom occurrence
Dim asm As AssemblyDocument = ThisDoc.Document
Dim occ As ComponentOccurrence = asm.ComponentDefinition.Occurrences(occIndex)
Dim part As PartDocument = occ.Definition.Document
'Get face using RefKey and Context
Dim face As Face = part.ReferenceKeyManager.BindKeyToObject(refKey, ctxt)
'Create proxy
Dim faceProxy As FaceProxy
occ.CreateGeometryProxy(face, faceProxy)
'Select face in assembly
asm.SelectSet.Select(faceProxy)
Here is sample how to obtain RefKey and Context from part environment and bind them back in part and assembly.
Get RefKey and Context in part
Dim face As Face = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kPartFaceFilter, "Select face")
Dim part As PartDocument = face.Parent.Parent.Document
Logger.Debug(part.DisplayName)
Dim refKey As Byte() = {}
Dim ctxt As Integer = part.ReferenceKeyManager.CreateKeyContext()
face.GetReferenceKey(refKey, ctxt)
Logger.Debug("RefKey:" & vbCrLf & String.Join(", ", refKey))
logger.Debug("Context: " & ctxt)
Get face in part
Dim refKey As Byte() = {1, 4, 5, ... see sample for full value ..., 0 }
Dim ctxt As Integer = 1
Dim part As PartDocument = ThisDoc.Document
Dim face As Face = part.ReferenceKeyManager.BindKeyToObject(refKey, ctxt)
part.SelectSet.Select(face)
Get faceProxy in assembly
Dim refKey As Byte() = {1, 4, 5, ... See sample for full value ..., 0 }
Dim ctxt As Integer = 1
Dim occIndex As Integer = 1
'Get part froom occurrence
Dim asm As AssemblyDocument = ThisDoc.Document
Dim occ As ComponentOccurrence = asm.ComponentDefinition.Occurrences(occIndex)
Dim part As PartDocument = occ.Definition.Document
'Get face using RefKey and Context
Dim face As Face = part.ReferenceKeyManager.BindKeyToObject(refKey, ctxt)
'Create proxy
Dim faceProxy As FaceProxy
occ.CreateGeometryProxy(face, faceProxy)
'Select face in assembly
asm.SelectSet.Select(faceProxy)
@WCrihfield wrote:... you would have to get the face from a component's referenced document, then use that component to get a reference to the proxy of that geometry within the 'parent' assembly's context ...
Can you elaborate on this, just in terms of connecting from a referenced doc. ultimately to the proxy geometry?
@WCrihfield wrote:... you would have to get the face from a component's referenced document, then use that component to get a reference to the proxy of that geometry within the 'parent' assembly's context ...
Can you elaborate on this, just in terms of connecting from a referenced doc. ultimately to the proxy geometry?
Hi @meGVGMF. The technique of using AttributeSets & Attributes to 'name' or 'tag' various things within Documents while using Inventor's API goes way back. Unfortunately those can not, and do not get copied from the 'original' objects in a PartDocument to their 'proxy' within the context of the assembly when you place that part into an assembly as a ComponentOccurrence. I assume the reason for this is that you can put multiple components into an assembly that all represent the same base PartDocument, and that would mean having the same exact Attribute & Name included in the assembly x number of times, causing chaos. When you place a component into an assembly, that just creates a virtual copy of the part's geometry (proxy) within the 'context' (3D coordinate space) of the assembly that is positioned and oriented the way you want it in relation to the assembly's own coordinate system. That copied version of geometry does not still have that AttributeSet or Attribute attached to it...only the original within the context of the part does. So, in order to identify which proxy face within the assembly represents the original face that had the Attribute, you must first have a reference to that original Face object (the one in the context of the part), then you must get the ComponentOccurrence object representing that part within the assembly, then you must use its CreateGeometryProxy() method and supply the 'Original' Face as the first 'input' variable, then input an empty FaceProxy type variable as the second 'input' variable, and that method will assign a value to that second variable that represents the 'FaceProxy' of that Face that exists within the context of the ComponentOccurrence's 'parent' assembly. But here's the point that most folks miss...that FaceProxy may still not be in the context of the 'top level' assembly, if that component's parent assembly was not yet the top level assembly. So, you must do this for each level of the assembly until the proxy object you get the reference to is in the context of the top level assembly, if you want to use that proxy for things like measurements or constraints within the top level assembly.
I have attached a PDF document that I created for myself and others a while back that also covers most of this, because it can be a bid of a mind bender for those not familiar with the concept yet.
Also, if you would like a copy of some iLogic code you could use for assigning names directly to top level proxy objects in the context of the main assembly just ask. Codes like that have been around for quite a while.
Wesley Crihfield
(Not an Autodesk Employee)
Hi @meGVGMF. The technique of using AttributeSets & Attributes to 'name' or 'tag' various things within Documents while using Inventor's API goes way back. Unfortunately those can not, and do not get copied from the 'original' objects in a PartDocument to their 'proxy' within the context of the assembly when you place that part into an assembly as a ComponentOccurrence. I assume the reason for this is that you can put multiple components into an assembly that all represent the same base PartDocument, and that would mean having the same exact Attribute & Name included in the assembly x number of times, causing chaos. When you place a component into an assembly, that just creates a virtual copy of the part's geometry (proxy) within the 'context' (3D coordinate space) of the assembly that is positioned and oriented the way you want it in relation to the assembly's own coordinate system. That copied version of geometry does not still have that AttributeSet or Attribute attached to it...only the original within the context of the part does. So, in order to identify which proxy face within the assembly represents the original face that had the Attribute, you must first have a reference to that original Face object (the one in the context of the part), then you must get the ComponentOccurrence object representing that part within the assembly, then you must use its CreateGeometryProxy() method and supply the 'Original' Face as the first 'input' variable, then input an empty FaceProxy type variable as the second 'input' variable, and that method will assign a value to that second variable that represents the 'FaceProxy' of that Face that exists within the context of the ComponentOccurrence's 'parent' assembly. But here's the point that most folks miss...that FaceProxy may still not be in the context of the 'top level' assembly, if that component's parent assembly was not yet the top level assembly. So, you must do this for each level of the assembly until the proxy object you get the reference to is in the context of the top level assembly, if you want to use that proxy for things like measurements or constraints within the top level assembly.
I have attached a PDF document that I created for myself and others a while back that also covers most of this, because it can be a bid of a mind bender for those not familiar with the concept yet.
Also, if you would like a copy of some iLogic code you could use for assigning names directly to top level proxy objects in the context of the main assembly just ask. Codes like that have been around for quite a while.
Wesley Crihfield
(Not an Autodesk Employee)
I may have to do a little more testing to be 100% sure, but the main thing that ModelStates does is causes there to be multiple Document objects present in the same File on disk, because each ModelState represents a different Document, and I would assume that since the AttributeManager object is accessed from the Document (Document.AttributeManager), then each different ModelState would have its own separately managed AttributeSets & Attributes. This is likely the main pain in the butt to work around. Simply getting the 'FactoryDocument' is not enough in that situation. You would have to ensure that if the Document you need to access is not currently the factory document, you would need to make it be the factory document first, then access its AttributeManager (only if you want to make changes to the Attributes in the document). If you only want to Read or check the documents existing attributes, you should be able to use the member document directly, instead of getting the factory document, because the factory document may be a different document, and not contain the attributes you are looking for. Have I helped, or just confused you more? 😂
Wesley Crihfield
(Not an Autodesk Employee)
I may have to do a little more testing to be 100% sure, but the main thing that ModelStates does is causes there to be multiple Document objects present in the same File on disk, because each ModelState represents a different Document, and I would assume that since the AttributeManager object is accessed from the Document (Document.AttributeManager), then each different ModelState would have its own separately managed AttributeSets & Attributes. This is likely the main pain in the butt to work around. Simply getting the 'FactoryDocument' is not enough in that situation. You would have to ensure that if the Document you need to access is not currently the factory document, you would need to make it be the factory document first, then access its AttributeManager (only if you want to make changes to the Attributes in the document). If you only want to Read or check the documents existing attributes, you should be able to use the member document directly, instead of getting the factory document, because the factory document may be a different document, and not contain the attributes you are looking for. Have I helped, or just confused you more? 😂
Wesley Crihfield
(Not an Autodesk Employee)
Can't find what you're looking for? Ask the community or share your knowledge.