Trouble placing custom iParts using iLogic

Trouble placing custom iParts using iLogic

christopher.pepin
Advocate Advocate
734 Views
8 Replies
Message 1 of 9

Trouble placing custom iParts using iLogic

christopher.pepin
Advocate
Advocate

I am having trouble figuring out how to have iLogic place multiple copies of a custom iPart and change the individual parameters.

 

I am trying to make iLogic rule to generate a grid of baffles that have a traveling wave pattern. I have a custom iPart for the baffle that has the length and thickness as keys and the amplitude of the wave pattern as a custom key. What I would like to do is have an iLogic rule that will take parameters from the user like spacing between baffles and place the parts and adjust each ones amplitude to whatever is required based on the other parameters. 

 

Attached is a test file I have been working on with the following rule.

 

 

ThisAssembly.BeginManage()

Dim componentA = Components.AddiPart("", "Waves.ipt", 2, position := Nothing, grounded := False, visible := True, appearance := Nothing)
Dim componentB = Components.AddiPart("", "Waves.ipt", 2, position := ThisDoc.Geometry.Point(0,0,4), grounded := False, visible := True, appearance := Nothing)

iPart.ChangeRow(componentB.Name, iPart.RowNumber(componentB.Name), 1 in)
ThisAssembly.EndManage()

 

 

I can place the parts successfully using the AddiPart but the only way I can find to change the custom parameter is using the ChangeRow function which alters the member file used by both of the parts. It was my understanding that custom iParts were supposed to generate a unique file for each part instead of reusing standard member files but that doesn't seem to be the case. If I place the iParts manually it creates seperate files for each but for my purposes I want to be able to create these parts through the iLogic.

 

So how do I get the iLogic to generate unique part files as I add new parts?

0 Likes
Accepted solutions (1)
735 Views
8 Replies
Replies (8)
Message 2 of 9

WCrihfield
Mentor
Mentor

Hi @christopher.pepin.  I admittedly have not worked much with iParts/iAssemblies for a while, but I think I may be able to help some.  I see in the online help for the Components.AddiPart() method, that it can be used not only for adding an iPart, but also for changing an existing iPart.  However, since that would still mean that you would have to have another variation (row) with the other value, that does not sound like what you want/need.  If you just want to change a parameter value for a component that has already been placed in an assembly, you could always just try digging down through the API structure, from that IManagedComponentOccurrence object, to the real component, then to the model document it represents, then through its ComponentDefinition to its Parameters.  Then try changing the parameter that way.  However, if multiple components are referencing the same model document as this one, this change will likely effect them all too.

Anyways, this (below) is what I had in mind for changing the parameter value, but I have not tested this theory yet myself and did not know what the parameter was named, because I don't have anything to test it on, and I do not generally like downloading random zip or rar type files on my work PC, due to security policy/concerns.

ThisAssembly.BeginManage()

Dim componentA = Components.AddiPart("", "Waves.ipt", 2, position := Nothing, grounded := False, visible := True, appearance := Nothing)
Dim componentB = Components.AddiPart("", "Waves.ipt", 2, position := ThisDoc.Geometry.Point(0,0,4), grounded := False, visible := True, appearance := Nothing)

'iPart.ChangeRow(componentB.Name, iPart.RowNumber(componentB.Name), 1 in)
Dim oOccB As ComponentOccurrence = componentB.Occurrence
Dim oOccBDef As PartComponentDefinition = oOccB.Definition
Dim oParams As Inventor.Parameters = oOccBDef.Parameters
Try
	oParams.Item("ParamName").Expression = "1 in"
Catch
	MsgBox("Getting/Setting value of parameter failed.", vbExclamation, "Parameter Access Failure")
End Try

ThisAssembly.EndManage()

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 3 of 9

A.Acheson
Mentor
Mentor
Accepted solution

You will likely have to move away from ilogic simple snippets that work with standard iparts to using the API and iPart factory. Here is a quick untested sample to add a custom occurrence from the factory file. Here is the link to the help file for factory file. 

' Open the factory document invisible.
    Dim oFactoryDoc As PartDocument = ThisApplication.Documents.Open("C:\temp\iPartFactory.ipt", False)

    ' Set a reference to the component definition.
    Dim oCompDef As PartComponentDefinition = oFactoryDoc.ComponentDefinition

    ' Make sure we have an iPart factory.
    If oCompDef.IsiPartFactory = False Then
        MsgBox "Chosen document is not a factory.", vbExclamation
        Exit Sub
    End If

    ' Set a reference to the factory.
    Dim oiPartFactory As iPartFactory = oCompDef.iPartFactory

    ' Get the number of rows in the factory.
    Dim iNumRows As Integer = oiPartFactory.TableRows.Count

    ' Create a new assembly document
    Dim oDoc As AssemblyDocument = ThisApplication.Documents.Add(kAssemblyDocumentObject, , True)

    Dim oOccs As ComponentOccurrences = oDoc.ComponentDefinition.Occurrences

    Dim oPos As Matrix = ThisApplication.TransientGeometry.CreateMatrix


        ' Add a translation along X axis
    oPos.SetTranslation(ThisApplication.TransientGeometry.CreateVector(0,0,0))

 'Input required info
  oiPartFactory.CreateCustomMember( FullFileName As String, [Row] As Variant, 
  [CustomInput] As Variant ) As iPartMember
        
  Dim oOcc As ComponentOccurrence = oOccs.Add(FullFileName, oPos)
  'Change the occurrence afterwards if needed
  'oOcc.ChangeRowOfiPartMember( NewRow As Variant, [CustomInput] As Variant )

 

 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
Message 4 of 9

christopher.pepin
Advocate
Advocate

@WCrihfield 

>However, if multiple components are referencing the same model document as this one, this change will likely effect them all too.

 

This seems to be the crux of my problem. I want to start with a blank assembly with only the iLogic rules and forms and have the rules place the part but I can't seem to get it to create separate part files for each custom iPart. It just doggedly insists on trying to reuse the same part file. It is actually even worse because instead of generating even a single copy of the part for the specific assembly from the part factory it tries to reference and change the member file in stored in the iPart factory itself.

0 Likes
Message 5 of 9

marcin_otręba
Advisor
Advisor

hi,

 

 

try this instead:

 

it use findrow function which will change ipart occurence to be this which was found. i tested it with my iparts and it works great. Be careful because column name is case sensitive.

ThisAssembly.BeginManage()

Dim componentA = Components.AddiPart("", "34-5-000020.ipt", 2, position := Nothing, grounded := False, visible := True, appearance := Nothing)
Dim componentB = Components.AddiPart("", "32-5-014371.ipt", 2, position := ThisDoc.Geometry.Point(0,0,4), grounded := False, visible := True, appearance := Nothing)


iPart.FindRow(componentC.Name, "Length", "=", "55 mm")
iPart.FindRow(componentB.Name,"bolt_qty","=","2","bolt_distance","=","300 mm")

'iPart.FindRow(componentB.Name,"PUT HERE YOUR IPART COLUMN NAME - case sensitive","=","1 in")

ThisAssembly.EndManage()

 

Hi, maybe you want to check my apps:


DrawingTools   View&ColoringTools   MRUFolders

0 Likes
Message 6 of 9

christopher.pepin
Advocate
Advocate

@marcin_otręba 

 

That seems to be having the same results as my original rule. To be clear both components are referencing the same custom ipart factory and the same row of that factory only with only the value of the custom parameter being different. Findrow seems to be just activating the same occurrence stored in the ipart factory's folder, for both components, instead of creating a new occurrence of the part. Then if I try to change the custom parameter it tries to save it back over the default member files in the ipart factory which I definitely don't want and both components end up changing.

0 Likes
Message 7 of 9

marcin_otręba
Advisor
Advisor

@christopher.pepin 

 

code is different than your,  in change component you need to indicate wchich member you want to use, in my sample it will find row by loocking given value of column.

 

If you give values wchich already are in ipart it will not save it, only change it, if you place some other value wchich does not match this from ipart factory or it will try to add row in ipart, then it must be saved, i think it is your situation.

 

 

i tested it using code, after running there was no prompt or suggestion to save ipart or data in ipart factory:

Dim ix As Integer=100



For i = 1 To ix 
	Dim componentA = Components.AddiPart("", "34-5-000020.ipt", 2, position := ThisDoc.Geometry.Point(0,0,i*20), grounded := False, visible := True, appearance := Nothing)
	
If i Mod 2 = 0 Then
	iPart.FindRow(componentA.Name, "Length", "=", "45 mm")
	Else
	iPart.FindRow(componentA.Name, "Length", "=", "60 mm")
End If

Next

 

 

assembly looks like:

marcin_otrba_0-1663601502137.png

 

marcin_otrba_1-1663601524828.png

 

Hi, maybe you want to check my apps:


DrawingTools   View&ColoringTools   MRUFolders

0 Likes
Message 8 of 9

christopher.pepin
Advocate
Advocate

@marcin_otręba 

 

I am not trying to add a row to the ipart factory, this is a custom ipart factory not a standard ipart factory. My understanding is that the proper way to set this up is as a custom ipart factory with the amplitude as a custom parameter as shown below, as there will not be a finite lists of values for it.

 

christopherpepin_0-1663603182180.png

 My goal here is to pick a single row and place several instances of that row changing only the amplitude of each instance. If I do this manually it works fine. When I go to place an instance of the custom ipart it prompts me to pick a location and filename for each new occurrence of the part as shown below.

 

christopherpepin_1-1663603470241.png

 

This is what I want. Each new instance should be a separate occurrence stored with the assembly. I don't want to try to preload the ipart table with every conceivable and findRow will only switch to a row that is already in the table. I want it to act exactly like it does when done manually. It is looking like this just isn't possible with straight ilogic and I will have to use the api like A.Acheson suggested.

 

0 Likes
Message 9 of 9

christopher.pepin
Advocate
Advocate

@A.Acheson 

 

I can't seem to figure out how to get this to work. I keep running into runtime errors, "Invalid procedure call or argument",  when it tries to call the any variation of the CreateCustomMember function. My code is currently as follows

 

 

 

Sub Compute()

    Dim oFactoryDoc As PartDocument
    Set oFactoryDoc = ThisApplication.Documents.Open(FACTORY PATH, True)
    
    Dim oCompDef As PartComponentDefinition
    Set oCompDef = oFactoryDoc.ComponentDefinition
    
    If oCompDef.IsiPartFactory = False Then
        MsgBox "Chosen Document is not a factory."
        Exit Sub
    End If
        
    Dim oiPartFactory As iPartFactory
    Set oiPartFactory = oCompDef.iPartFactory
    
    Dim oDoc As AssemblyDocument
    Set oDoc = ThisApplication.Documents.Open(ASSEMBLY PATH, True)
    
    Dim oAsmCompDef As AssemblyComponentDefinition
    Set oAsmCompDef = oDoc.ComponentDefinition
    
    Dim partAMemeber As iPartMember
    partAMember = oiPartFactory.CreateCustomMember(NEW OCCURENCE A PATH, 2, "1.5")
    
    Dim partBMemeber As iPartMember
    partBMember = oiPartFactory.CreateCustomMember(NEW OCCURENCE B PATH, 2, 1)

     Dim oOccs As ComponentOccurrences
     Set oOccs = oDoc.ComponentDefinition.Occurrences
     
     Dim oPos As Matrix
     Set oPos = ThisApplication.TransientGeometry.CreateMatrix
     
     
     
     Dim oOccA As ComponentOccurrence
     'Set oOccA = oOccs.AddCustomiPartMember(FACTORY PATH, oPos, NEW OCCURENCE A PATH, 2, 1)
     Set oOccA = oOccs.Add(NEW OCCURENCE A PATH, oPos)
     
     Dim oVec As Vector
     Set oVec = ThisApplication.TransientGeometry.CreateVector(0, 0, 4)
     
     Call oPos.SetTranslation(oVec, False)
     
     Dim oOccB As ComponentOccurrence
     'Set oOccB = oOccs.AddCustomiPartMember(FACTORY PATH, oPos, NEW OCCURENCE B PATH, 2, 1.5)
     Set oOccB = oOccs.Add(NEW OCCURENCE B PATH, oPos)
End Sub

 

 

 

I have tried creating the custom member file first and then adding it to the assembly files occurrences and calling the addCustomiPartMember function built into the componentOccurences, the portion I have commented out. Both produce the same error but I can't see anything wrong with the arguments I am providing. I have tried providing the custom parameters as both a string and as just a plain number.

0 Likes