Announcements
Attention for Customers without Multi-Factor Authentication or Single Sign-On - OTP Verification rolls out April 2025. Read all about it here.

UCS to UCS constraint for subassembly

Saikiran_arakeri
Enthusiast

UCS to UCS constraint for subassembly

Saikiran_arakeri
Enthusiast
Enthusiast

Hi, I am trying to perform a UCS to UCS via C# and Inventor API. There are 2 UCS here, 

Saikiran_arakeri_0-1689759690321.png

 

Assembly 3 is the UCS of the subassembly and Assembly 3:1 is the Local CS I have created. I am trying to constraint 3:1 with 3.  @Andrii_Humeniuk @Curtis_Waguespack @A.Acheson @WCrihfield 

0 Likes
Reply
Accepted solutions (1)
535 Views
4 Replies
Replies (4)

WCrihfield
Mentor
Mentor
Accepted solution

Hi @Saikiran_arakeri.  Judging from the image you posted above, neither of those two UCS objects are really 'local'.  The one named "ASM_Assembly3:1" appears to be defined within the sub assembly named "Assembly20:1".  Then the UCS named "ASM_Assembly3" appears to be defined down within a sub assembly named "Assembly3:1" that is within that other sub assembly.  This is a pretty complex situation to write a code to solve for you, but I have given it a try for you.  Below is an iLogic rule that should create the necessary constraints.  Just so you know, the 'UCS to UCS constraint' is not a real thing, there is just an iLogic shortcut snipped name that way for that task.  What it actually does is create 3 flush constraints.  It creates a flush constraint between a specific WorkPlane within one UCS to the same WorkPlane within the other UCS, and does that for all 3 WorkPlanes within both UCS's.  So, that is what this iLogic rule is doing.  I am using regular Inventor API code for this task, instead of that iLogic shortcut snippet, because of the complexity of this situation.  Let me know how this works for you.

Sub Main
	If ThisDoc.Document.DocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then
		MsgBox("An Assembly Document must be active for this rule to work. Exiting.", vbCritical, "")
		Exit Sub
	End If
	Dim oADoc As AssemblyDocument = ThisDoc.Document
	Dim oADef As AssemblyComponentDefinition = oADoc.ComponentDefinition
	Dim oOccs As ComponentOccurrences = oADef.Occurrences
	Dim oConsts As AssemblyConstraints = oADef.Constraints
	'get the first level component that represents the first sub assembly, by name
	Dim oSubAsmOcc As ComponentOccurrence = oOccs.ItemByName("Assembly20:1")
	'get the UCS defined within the definition of that component
	Dim oSubAsmUCS As UserCoordinateSystem = oSubAsmOcc.Definition.UserCoordinateSystems.Item("ASM_Assembly3:1")
	'step up the proxy ladder to get the UCS for this in the context of the top assembly (only 1 step needed here)
	Dim oSubAsmUCSProxy As UserCoordinateSystemProxy = Nothing
	oSubAsmOcc.CreateGeometryProxy(oSubAsmUCS, oSubAsmUCSProxy)
	'get the second level component, within the other component, by name
	Dim oSubSubAsmOcc As ComponentOccurrence = oSubAsmOcc.Definition.Occurrences.ItemByName("Assembly3:1")
	'get the UCS that is defined within the definition of that component 
	Dim oSubSubAsmUCS As UserCoordinateSystem = oSubSubAsmOcc.Definition.UserCoordinateSystems.Item("ASM_Assembly3")
	'step up the proxy ladder 2 steps to get the UCS for this in the context of the top assembly
	'first create a variable to hold the proxy object we are about to get
	Dim oSubSubAsmUCSProxy1 As UserCoordinateSystemProxy = Nothing
	'now set that variable's value using this method of that UCS's owning component
	oSubSubAsmOcc.CreateGeometryProxy(oSubSubAsmUCS, oSubSubAsmUCSProxy1)
	'that proxy is in the context of its parent component, not the main assembly yet, because it was a second level component
	'now create another variable for the next step up proxy object
	Dim oSubSubAsmUCSProxy2 As UserCoordinateSystemProxy = Nothing
	'now use this method of the parent component to set the value of that variable, using that last lower level proxy as input
	oSubAsmOcc.CreateGeometryProxy(oSubSubAsmUCSProxy1, oSubSubAsmUCSProxy2)
	'now create the constraints (UCS to UCS constraint is just 3 WorkPlane Flush constraints behind the scenes)
	'these constraints are created in the context of the main assembly, so the participants also need to be in that context
	Dim oFConst1, oFConst2, oFConst3 As FlushConstraint
	oFConst1 = oConsts.AddFlushConstraint(oSubAsmUCSProxy.XYPlane, oSubSubAsmUCSProxy2.XYPlane, 0.0)
	oFConst2 = oConsts.AddFlushConstraint(oSubAsmUCSProxy.XZPlane, oSubSubAsmUCSProxy2.XZPlane, 0.0)
	oFConst3 = oConsts.AddFlushConstraint(oSubAsmUCSProxy.YZPlane, oSubSubAsmUCSProxy2.YZPlane, 0.0)
	oADoc.Update
End Sub

If this solved your problem, or answered your question, please click ACCEPT SOLUTION .
Or, if this helped you, please click (LIKE or KUDOS) 👍.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Saikiran_arakeri
Enthusiast
Enthusiast

That worked @WCrihfield, used the logic and tweaked the code a little. Thank you.

0 Likes

Saikiran_arakeri
Enthusiast
Enthusiast

Trying to Constraint PRT_Part5 (PCS) and PRT_Part5 (LCS). Here is the tree.

 

Saikiran_arakeri_0-1689829421552.png

Saikiran_arakeri_1-1689829511920.png

 

@WCrihfield @A.Acheson 

@Andrii_Humeniuk  @Curtis_Waguespack 

 

0 Likes

WCrihfield
Mentor
Mentor

Hi @Saikiran_arakeri.  Since the UCS objects are getting a bit deeper in this situation, I decided to use a slightly different strategy.  I am using functionality similar to the iLogic MakePath (Link1, Link2) tool, which allows us to specify the name of each component along the path to a lower level component, from top to bottom in the correct order, as a way of specifying which lower level component we are targeting, in one step.  And I am also utilizing the Component.InventorComponent iLogic snippet to help retrieve that specific component that way.  Then I use the normal API method to get the first 'parent' level proxy of the UCS that was in that component.  Then I am using a custom recursive function to help step up the proxy ladder to get the UCS proxy that is in the top level assembly context.  Then I am doing the 3 constraints using the same API process as before.

I have not tested this yet, so let me know how this works for you.

Sub Main
	If ThisDoc.Document.DocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then
		MsgBox("An Assembly Document must be active for this rule to work. Exiting.", vbCritical, "")
		Exit Sub
	End If
	Dim oADoc As AssemblyDocument = ThisDoc.Document
	
	Dim oAsm3Comp As ComponentDefinition = Component.InventorComponent({"Assembly20:1", "Assembly3" })
	Dim oUCSinAsm3 As UserCoordinateSystem = oAsm3Comp.Definition.UserCoordinateSystems.Item("PRT_Part5")
	Dim oUCSInAsm3Proxy As UserCoordinateSystemProxy = Nothing
	oAsm3Comp.CreateGeometryProxy(oUCSinAsm3, oUCSInAsm3Proxy)
	Dim oUCSinAsm3TopProxy As UserCoordinateSystemProxy = GetTopLevelProxy(oUCSInAsm3Proxy)

	Dim oPart5Comp As ComponentDefinition = Component.InventorComponent({"Assembly20:1", "Assembly3", "Part5" })
	Dim oUCSinPart5 As UserCoordinateSystem = oPart5Comp.Definition.UserCoordinateSystems.Item("PRT_Part5")
	Dim oUCSInPart5Proxy As UserCoordinateSystemProxy = Nothing
	oPart5Comp.CreateGeometryProxy(oUCSinPart5, oUCSInPart5Proxy)
	Dim oUCSinPart5TopProxy As UserCoordinateSystemProxy = GetTopLevelProxy(oUCSInPart5Proxy)

	Dim oConsts As AssemblyConstraints = oADoc.ComponentDefinition.Constraints
	Dim oFConst1, oFConst2, oFConst3 As FlushConstraint
	oFConst1 = oConsts.AddFlushConstraint(oUCSinAsm3TopProxy.XYPlane, oUCSinPart5TopProxy.XYPlane, 0.0)
	oFConst2 = oConsts.AddFlushConstraint(oUCSinAsm3TopProxy.XZPlane, oUCSinPart5TopProxy.XZPlane, 0.0)
	oFConst3 = oConsts.AddFlushConstraint(oUCSinAsm3TopProxy.YZPlane, oUCSinPart5TopProxy.YZPlane, 0.0)
	oADoc.Update
End Sub

Function GetTopLevelProxy(oInputObj As Object) As Object
	If oInputObj Is Nothing Then Return Nothing
	If TypeName(oInputObj).ToUpper.EndsWith("PROXY") = False Then Return Nothing
	Dim oCOcc As ComponentOccurrence = oInputObj.ContainingOccurrence
	If oCOcc Is Nothing Then Return oInputObj
	Dim oNextLevelUpProxy As Object = Nothing
	oCOcc.CreateGeometryProxy(oInputObj, oNextLevelUpProxy)
	If oCOcc.ParentOccurrence Is Nothing Then
		Return oNextLevelUpProxy
	Else
		GetTopLevelProxy(oNextLevelUpProxy)
	End If
End Function

If this solved your problem, or answered your question, please click ACCEPT SOLUTION .
Or, if this helped you, please click (LIKE or KUDOS) 👍.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)