iLogic Make Concentric Constraint

iLogic Make Concentric Constraint

logan_armagost
Participant Participant
250 Views
2 Replies
Message 1 of 3

iLogic Make Concentric Constraint

logan_armagost
Participant
Participant

I have been struggling with this all day now. I just want to make a simple concentric mate between two hole features on two parts in an assembly using iLogic. The two parts in the assembly may be any combination of a list of parts that are very similar (all the features are in the same order and have the same names, the overall length and/or width of the parts are just different). Much of the stuff I've found online involves manually renaming a face using the interface, then using the Constraints.AddMate command, passing the occurrence names and face names as arguments. I don't want to have to go through all these parts and rename the faces. And somehow it seems that every face is Face0 until I rename it manually, so I don't think this method will work for me here. It really seems like I should be able to make this constraint based on the hole features. I know the name of the component occurrence (and it's the same every time) and I know the name of the hole features (and they're the same every time). I can successfully find the cylindrical faces I'm looking for with iLogic. I can verify they're the correct faces by returning the face type as cylindrical and the radii of the cylindrical faces. It's one hole per hole feature. So I have the faces in iLogic as 'face' objects, but I can't get the constraint to work. Here's some of the code I've used to get the faces through the hole features and attempt to create a constraint:

 

Sub HandleUSBReplacement()

    Dim doc As Document = ThisApplication.ActiveDocument
    Dim asmDoc As AssemblyDocument = doc

    ' Get components
    Dim usbComp As ComponentOccurrence = asmDoc.ComponentDefinition.Occurrences.ItemByName("USB:1")
    Dim lsbComp As ComponentOccurrence = asmDoc.ComponentDefinition.Occurrences.ItemByName("LSB:2")
    Dim hole1 As HoleFeature = usbComp.Definition.Features.Item("Hole6")
    Dim hole2 As HoleFeature = lsbComp.Definition.Features.Item("Hole6")
    Dim face1 As Face = hole1.SideFaces(1)     Dim face2 As Face = hole2.SideFaces(1)     ' Verify correct faces found     Logger.Debug("Face1 type: " & face1.SurfaceType.ToString())     Logger.Debug("Face2 type: " & face2.SurfaceType.ToString())     Logger.Debug("Face1 Radius: "face1.Geometry.Radius)     Logger.Debug("Face2 Radius: "face2.Geometry.Radius) ' This is proof that the face has been found as there is no other cylindrical face of that radius in the part^^     Try         Dim newConstraint As AssemblyConstraint = asmDoc.ComponentDefinition.Constraints.AddMateConstraint(face1, face2, 0)         newConstraint.Name = "Concentric1"     Catch ex As Exception         MsgBox("Error creating constraint: " & ex.Message)     End Try End Sub

 

This method above throws this error (at the line that attempts to make the constraint): "Unspecified error (Exception from HRESULT: 0x80004005 (E_FAIL))"

From what I can tell, this could be almost anything and could not be less helpful in my efforts to debug the issue lol. 

 

After I couldn't get this method to work, I went back to trying the method found in the snippets (Constraints.AddMate). I figured surely there is a way to take the face object I was successfully able to find, set the name of the face within the iLogic rule, then mate them using the names. I can make the constraint manually as you normally would in the interface then use the "Capture current state (add.constraint) within the iLogic editing window and I see the Constraints.AddMate command and the two faces are both apparently Face0, which is odd. I think making the constraint assigns the names automatically. When I replace the part I'm trying to mate with one of the other similar ones (that I haven't manually mated) and try to use the command with 'Face0', it says "No work feature or named entity with the name "Face0" was found in component: "USB:1". This is why I'm now trying to find the face first using the name of the hole feature, then name it, then use that name to build the constraint. Here's what I have for that strategy so far (portion of the script that's relevant, hence the missing Sub Main and End sub and):

 

                    Dim transaction As Transaction
		    transaction = ThisApplication.TransactionManager.StartTransaction(doc, "Replace Upper Spreader Bar")
		
		    Try
		        Dim oAsmDoc As AssemblyDocument = doc
		        		        
		        Logger.Debug("Getting components...")
		        Dim usb1Comp As ComponentOccurrence = oAsmDoc.ComponentDefinition.Occurrences.ItemByName("USB:1")
		        Dim lsb2Comp As ComponentOccurrence = oAsmDoc.ComponentDefinition.Occurrences.ItemByName("LSB:2")
		        
		        ' Get hole features
		        Logger.Debug("Getting hole features...")
		        Dim usb1Hole As HoleFeature = usb1Comp.Definition.Features.Item("Hole6")
		        Dim lsb2Hole As HoleFeature = lsb2Comp.Definition.Features.Item("Hole2")
				
		        Dim namedEntities = ThisDoc.NamedEntities
		        Logger.Debug("got named entities")
		        ' Find and rename the cylindrical faces
		        For Each f As Face In usb1Hole.Faces
		            If f.SurfaceType = SurfaceTypeEnum.kCylinderSurface Then
				Logger.Debug("name of face before rename:" & namedEntities.GetName(f))
namedEntities.SetName(f, "USB_Hole6_CylFace")
Logger.Debug("name of face:" & namedEntities.GetName(f)) Exit For End If Next For Each f As Face In lsb2Hole.Faces If f.SurfaceType = SurfaceTypeEnum.kCylinderSurface Then namedEntities.SetName(f, "LSB_Hole2_CylFace") Exit For End If Next ' Now use the named faces in Constraints.AddMate Constraints.AddMate("Concentric1", "LSB:2", "LSB_Hole2_CylFace", _ "USB:1", "USB_Hole6_CylFace", _ e1InferredType := InferredTypeEnum.kInferredLine, _ e2InferredType := InferredTypeEnum.kInferredLine, _ solutionType := MateConstraintSolutionTypeEnum.kUndirectedSolutionType) transaction.End() Catch ex As Exception transaction.Abort() Logger.Debug("Error: " & ex.Message) End Try

 This one gave me a better error (i guess?) but I still don't know what to do about it:

"The method or operation is not implemented." 

And this error seems to occur at the line where I'm trying to set the name. The debug line above the line attempting to set the name reveals that there is no name prior to setting it (empty string).

 

What is the best way to go about this? It feels like such a simple ask. 2 parts. 2 holes. create a concentric constraint. And I just cannot get it working for the life of me. Any and all advice is appreciated. I really don't want to go through dozens of parts and manually rename the faces. Ironically, at this point that probably would've been the faster solution. But I'm determined that what I'm trying to do should be very possible to accomplish within iLogic.

 

Thanks

0 Likes
251 Views
2 Replies
Replies (2)
Message 2 of 3

logan_armagost
Participant
Participant

Oh boy, I finally got it. Posting here in case someone else in the future ever finds themselves in this hell I've been in all day haha. 

 

I was actually quite close. The fix was I needed to get the NamedEntities for each specific part document:

 

                        Dim oAsmDoc As AssemblyDocument = doc
		        Logger.Debug("Getting components...")
		        Dim usb1Comp As ComponentOccurrence = oAsmDoc.ComponentDefinition.Occurrences.ItemByName("USB:1")
		        Dim lsb2Comp As ComponentOccurrence = oAsmDoc.ComponentDefinition.Occurrences.ItemByName("LSB:2")
		        
		        Logger.Debug("Getting hole features...")
		        Dim usb1Hole As HoleFeature = usb1Comp.Definition.Features.Item("Hole6")
		        Dim lsb2Hole As HoleFeature = lsb2Comp.Definition.Features.Item("Hole2")
				
				Logger.Debug("Getting part docs")
				Dim usb1Doc As PartDocument = usb1Comp.Definition.Document
				Dim lsb2Doc As PartDocument = lsb2Comp.Definition.Document
				
				Logger.Debug("Getting named entities objects")
		        Dim usbNamedEntities As NamedEntities = iLogicVb.Automation.GetNamedEntities(usb1Doc)
		        Dim lsbNamedEntities As NamedEntities = iLogicVb.Automation.GetNamedEntities(lsb2Doc)

				Logger.Debug("got named entities")
				
		        ' Find and rename the cylindrical faces
		        For Each f As Face In usb1Hole.Faces
		            If f.SurfaceType = SurfaceTypeEnum.kCylinderSurface Then
						Logger.Debug("name of usb face before rename:" & usbNamedEntities.GetName(f))
		                usbNamedEntities.SetName(f, "USB_Hole6_CylFace")
						Logger.Debug("name after:" & usbNamedEntities.GetName(f))
		                Exit For
		            End If
		        Next

 

 

0 Likes
Message 3 of 3

logan_armagost
Participant
Participant

This no longer works if I run the external rule from within another rule using iLogicRunExternalRule. Makes zero sense, but it says it can't find the component. When run manually (right click>run rule from iLogic browser), it works fine. It will even work on the assembly it just failed on. Cannot figure out why. 

0 Likes