New Substitute>Derive Assembly>Bounding Box (.ipt only) - iLogic please.

New Substitute>Derive Assembly>Bounding Box (.ipt only) - iLogic please.

andrew_canfield
Collaborator Collaborator
2,729 Views
32 Replies
Message 1 of 33

New Substitute>Derive Assembly>Bounding Box (.ipt only) - iLogic please.

andrew_canfield
Collaborator
Collaborator

 

Hello

Going to search the forum to find something which will copy the workflow below - the result will be a simplified part  made up of Bounding Boxes. not too sure how the options are set using ilogic.

 

 

Substitue Derived Part.JPG

 

Regards

 

Andrew

0 Likes
Accepted solutions (4)
2,730 Views
32 Replies
Replies (32)
Message 2 of 33

J-Camper
Advisor
Advisor

I had some code to replace part with derived part within an assembly, and modified it to do the open assembly instead:

 

Sub Main
	If ThisApplication.ActiveDocumentType <> kAssemblyDocumentObject Then MessageBox.Show("This rule is designed to only work in assembly documents.", "Wrong Document Type") : Exit Sub
	
	Dim AsmDoc As AssemblyDocument = ThisApplication.ActiveDocument
	Dim FileName As String = AsmDoc.FullFileName : FileName = Left(FileName, (FileName.Length-4)) & "_SUB" & ".ipt"
	Dim NewDoc As PartDocument = ThisApplication.Documents.Add(DocumentTypeEnum.kPartDocumentObject, , False) 'include path to template file [if defualt is insufficient] between ,  , after DocumentTypeEnum.kPartDocumentObject
	Dim oDerivedAsmDef As DerivedAssemblyDefinition = NewDoc.ComponentDefinition.ReferenceComponents.DerivedAssemblyComponents.CreateDefinition(AsmDoc.FullFileName)
	
	'Derived Assembly Options:
	oDerivedAsmDef.ScaleFactor = 1
	oDerivedAsmDef.ReducedMemoryMode = True
	oDerivedAsmDef.UseColorOverridesFromSource = True
	oDerivedAsmDef.IncludeAllTopLeveliMateDefinitions = DerivedComponentOptionEnum.kDerivedExcludeAll
	oDerivedAsmDef.IncludeAllTopLevelParameters = DerivedComponentOptionEnum.kDerivedExcludeAll
	oDerivedAsmDef.IncludeAllTopLevelSketches = DerivedComponentOptionEnum.kDerivedExcludeAll
	oDerivedAsmDef.IncludeAllTopLevelWorkFeatures = DerivedComponentOptionEnum.kDerivedExcludeAll
	oDerivedAsmDef.DeriveStyle = DerivedComponentStyleEnum.kDeriveAsMultipleBodies
	oDerivedAsmDef.InclusionOption = DerivedComponentOptionEnum.kDerivedBoundingBox

	Call NewDoc.ComponentDefinition.ReferenceComponents.DerivedAssemblyComponents.Add(oDerivedAsmDef)

	Try
		NewDoc.SaveAs(FileName, False)
	Catch
		MessageBox.Show(NewDoc.DisplayName & " cannot be overwritten.", "Terminating")
		NewDoc.Close(True)
		Exit Sub
	End Try
	
	ThisApplication.Documents.Open(NewDoc.FullDocumentName, True)
	
End Sub
	

 

Let me know if you have any questions or if this is not working as intended

Message 3 of 33

andrew_canfield
Collaborator
Collaborator

Many Thanks, sorry it's taken a while to test but there's a hickup. I was hoping for only the parts to be blocked out - not the assembly. The result is on the left of the picture & the wish is for the image on the right - possible?

DeriveBlock.jpg

Regards

Andrew

0 Likes
Message 4 of 33

J-Camper
Advisor
Advisor
Accepted solution

Easy tweak, Just changed the InclusionOption to Exclude all then gathered all the Parts and subassembly parts into an ObjectCollection with a custom function.  Then set the InclusionOption for each Part occurrence individually before setting the definition to the new part document:

Sub Main
	If ThisApplication.ActiveDocumentType <> kAssemblyDocumentObject Then MessageBox.Show("This rule is designed to only work in assembly documents.", "Wrong Document Type") : Exit Sub
	
	Dim AsmDoc As AssemblyDocument = ThisApplication.ActiveDocument
	Dim FileName As String = AsmDoc.FullFileName : FileName = Left(FileName, (FileName.Length-4)) & "_SUB" & ".ipt"
	Dim NewDoc As PartDocument = ThisApplication.Documents.Add(DocumentTypeEnum.kPartDocumentObject, , False) 'include path to template file [if defualt is insufficient] between ,  , after DocumentTypeEnum.kPartDocumentObject
	Dim oDerivedAsmDef As DerivedAssemblyDefinition = NewDoc.ComponentDefinition.ReferenceComponents.DerivedAssemblyComponents.CreateDefinition(AsmDoc.FullFileName)
	
	'Derived Assembly Options:
	oDerivedAsmDef.ScaleFactor = 1
	oDerivedAsmDef.ReducedMemoryMode = True
	oDerivedAsmDef.UseColorOverridesFromSource = True
	oDerivedAsmDef.IncludeAllTopLeveliMateDefinitions = DerivedComponentOptionEnum.kDerivedExcludeAll
	oDerivedAsmDef.IncludeAllTopLevelParameters = DerivedComponentOptionEnum.kDerivedExcludeAll
	oDerivedAsmDef.IncludeAllTopLevelSketches = DerivedComponentOptionEnum.kDerivedExcludeAll
	oDerivedAsmDef.IncludeAllTopLevelWorkFeatures = DerivedComponentOptionEnum.kDerivedExcludeAll
	oDerivedAsmDef.DeriveStyle = DerivedComponentStyleEnum.kDeriveAsMultipleBodies
	oDerivedAsmDef.InclusionOption = DerivedComponentOptionEnum.kDerivedExcludeAll
	
	'Limit bounding box to part files only
	Dim partCol As ObjectCollection = GetOnlyParts(oDerivedAsmDef.Occurrences)
	
	For Each Oc As DerivedAssemblyOccurrence In partCol
		Oc.InclusionOption = DerivedComponentOptionEnum.kDerivedBoundingBox
	Next

	Call NewDoc.ComponentDefinition.ReferenceComponents.DerivedAssemblyComponents.Add(oDerivedAsmDef)

	Try
		NewDoc.SaveAs(FileName, False)
	Catch
		MessageBox.Show(NewDoc.DisplayName & " cannot be overwritten.", "Terminating")
		NewDoc.Close(True)
		Exit Sub
	End Try
	
	ThisApplication.Documents.Open(NewDoc.FullDocumentName, True)
	
End Sub

Function GetOnlyParts(mainCol As DerivedAssemblyOccurrences) As ObjectCollection
	Dim Result As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection
	For Each Oc As DerivedAssemblyOccurrence In mainCol
		If Oc.IsAssembly = False
			Result.Add(Oc)
		Else
			For Each OcSub As DerivedAssemblyOccurrence In GetOnlyParts(Oc.SubOccurrences)
				Result.Add(OcSub)
			Next
		End If
	Next
	Return Result
End Function

Let me know if you have any questions, or if it is not working as intended.

Message 5 of 33

andrew_canfield
Collaborator
Collaborator

Many Thanks

One day i'll understand!

0 Likes
Message 6 of 33

andrew_canfield
Collaborator
Collaborator

Working exactly as I'd hoped but could a few extra's be added - if possible?

Many existing assemblies have a LoD or View Rep set (which are best avoided) - if an additional  LoD /View Rep called 'For_GA' is added to the can the ilogic pick up this option?

Secondly, some shading collision can be seen where there's a surface on a surface - could the 'Single solid body merging out seams' be set?

LoD Switches.jpg

 

Difficult to say if that's everything, certainly 99% I feel.

 

[The next project would be to iterate through sub assemblies - running this code, creating simple versions of the sub assemblies, then replace the sub assembly with the part. This would leave the LoD at master & the browser containing simplified parts]

 

Thanks again

 

Andrew

0 Likes
Message 7 of 33

J-Camper
Advisor
Advisor

The derive style is easy to change:

'Replace Line:
oDerivedAsmDef.DeriveStyle = DerivedComponentStyleEnum.kDeriveAsMultipleBodies
'With the Line:
oDerivedAsmDef.DeriveStyle = DerivedComponentStyleEnum.kDeriveAsSingleBodyNoSeams

As for the view representations, are you saying you want to export the subassemblies in their master view/LOD state or you want to export them in the state of a custom view/LOD?

 

If it's master you should be able to just change the view/LOD of the main assembly to mater and all others should follow suite before running the rule. 

 

Otherwise there will have to be additional code to check and set View/LOD for subassemblies before collection parts within those subassemblies.

0 Likes
Message 8 of 33

andrew_canfield
Collaborator
Collaborator

Hello

 

I've been searching & can't find an example of deriving the current LoD setting (or view rep)- the code always appears to export the master.

 

Managed to find (guess it was already in the code) the export 'No seams' option.

 

Many existing assemblies contain suppressed part which I'd like to exclude from the substitute.

My efforts are generating a few error messages!

 

Regards

 

Andrew

 

0 Likes
Message 9 of 33

J-Camper
Advisor
Advisor

There is a way to link a view representation in the main assembly:

 

oDerivedPartDef.ActiveDesignViewRepresentation = RepID 'Where RepID is a string of the View rep name

 

but I'm not sure if that would affect the Part collection function or if that function needs to be modified to verify visibility with the desired View representation.  I've done more automated part derivations than assembly derivations in my time, but it should be doable either way.

0 Likes
Message 10 of 33

andrew_canfield
Collaborator
Collaborator

Sorry for the trouble but..


Error on Line 19 : 'oDerivedPartDef' is not declared. It may be inaccessible due to its protection level.

0 Likes
Message 11 of 33

J-Camper
Advisor
Advisor

Sorry I pulled that line out of my derived part sub routine and didn't change the variable name.  Use this instead:

oDerivedAsmDef.ActiveDesignViewRepresentation = RepID 'Where RepID is a string of the View rep name

DerivedAssemblyDefinition Object [link to the help file for this definition's Methods/Properties]

 

It looks like you can do a similar thing with the LOD if you still need to.

 

0 Likes
Message 12 of 33

andrew_canfield
Collaborator
Collaborator

The parameter is incorrect. (Exception from HRESULT: 0x80070057 (E_INVALIDARG))

 

I've attached the test assembly - added the code on line 26.

 

Thanks for the effort, didn't realise it would be so awkward.

 

Regards

 

Andrew 

0 Likes
Message 13 of 33

J-Camper
Advisor
Advisor
Accepted solution

I don't have a 2018 version of Inventor so the sample files got saved to 2019 files while i tested them, but here is the code:

Sub Main
	If ThisApplication.ActiveDocumentType <> kAssemblyDocumentObject Then MessageBox.Show("This rule is designed to only work in assembly documents.", "Wrong Document Type") : Exit Sub
	'Main Setup:
	Dim AsmDoc As AssemblyDocument = ThisApplication.ActiveDocument
	Dim FileName As String = AsmDoc.FullFileName : FileName = Left(FileName, (FileName.Length-4)) & "_SUB" & ".ipt"
	
	'ViewRep Sample Setup:
	Dim RepID As String = ""
	Dim RepIDlist As New List(Of String)
	'Get List from file so we can choose view from list. This Can be automated with desired name
	For Each View In AsmDoc.ComponentDefinition.RepresentationsManager.DesignViewRepresentations
		RepIDlist.Add(View.Name)
	Next	

	'Temporarily choosing view from list. This can be automated with desired name
	RepID = InputListBox("", RepIDlist, RepIDlist.Item(0), Title := "Title", ListName := "List")
	If RepID = "" Then RepID = "Master" 'Setting a Default Value for nothing selected
	'Set View representation so visibility can be verified
	AsmDoc.ComponentDefinition.RepresentationsManager.DesignViewRepresentations.Item(RepID).Activate

	'New Document Setup:
	Dim NewDoc As PartDocument = ThisApplication.Documents.Add(DocumentTypeEnum.kPartDocumentObject, , False) 'include path to template file [if defualt is insufficient] between ,  , after DocumentTypeEnum.kPartDocumentObject
	Dim oDerivedAsmDef As DerivedAssemblyDefinition = NewDoc.ComponentDefinition.ReferenceComponents.DerivedAssemblyComponents.CreateDefinition(AsmDoc.FullFileName)

	'Derived Assembly Options:
	oDerivedAsmDef.ScaleFactor = 1
	oDerivedAsmDef.ReducedMemoryMode = True
	oDerivedAsmDef.UseColorOverridesFromSource = True
	oDerivedAsmDef.IncludeAllTopLeveliMateDefinitions = DerivedComponentOptionEnum.kDerivedExcludeAll
	oDerivedAsmDef.IncludeAllTopLevelParameters = DerivedComponentOptionEnum.kDerivedExcludeAll
	oDerivedAsmDef.IncludeAllTopLevelSketches = DerivedComponentOptionEnum.kDerivedExcludeAll
	oDerivedAsmDef.IncludeAllTopLevelWorkFeatures = DerivedComponentOptionEnum.kDerivedExcludeAll
	oDerivedAsmDef.DeriveStyle =  DerivedComponentStyleEnum.kDeriveAsSingleBodyNoSeams
	oDerivedAsmDef.InclusionOption = DerivedComponentOptionEnum.kDerivedExcludeAll
	oDerivedAsmDef.ActiveDesignViewRepresentation = RepID 'Where RepID is a string of the View rep name

	'Limit bounding box to part files only
	Dim partCol As ObjectCollection = GetOnlyParts(oDerivedAsmDef.Occurrences)
	
	For Each Oc As DerivedAssemblyOccurrence In partCol
		Oc.InclusionOption = DerivedComponentOptionEnum.kDerivedBoundingBox
	Next

	Call NewDoc.ComponentDefinition.ReferenceComponents.DerivedAssemblyComponents.Add(oDerivedAsmDef)

	Try
		NewDoc.SaveAs(FileName, False)
	Catch
		MessageBox.Show(NewDoc.DisplayName & " cannot be overwritten.", "Terminating")
		NewDoc.Close(True)
		Exit Sub
	End Try
	
	ThisApplication.Documents.Open(NewDoc.FullDocumentName, True)
	
End Sub

Function GetOnlyParts(mainCol As DerivedAssemblyOccurrences) As ObjectCollection
	Dim Result As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection
	For Each Oc As DerivedAssemblyOccurrence In mainCol
		If Oc.IsAssembly = False
			If Oc.ReferencedOccurrence.Suppressed = False And Oc.ReferencedOccurrence.Visible = True
				Result.Add(Oc)
			End If
		Else
			For Each OcSub As DerivedAssemblyOccurrence In GetOnlyParts(Oc.SubOccurrences)
				If OcSub.ReferencedOccurrence.Suppressed = False And OcSub.ReferencedOccurrence.Visible = True
					Result.Add(OcSub)
				End If
			Next
		End If
	Next
	Return Result
End Function

Looks like I had to set the view representation before I could test the solid bodies for visibiliy/suppression, which was added to the GetOnlyParts Function.  If subassembly view reps are associated with the main assembly View Representation, It should work as intended, Otherwise digging through sub assemblies might require some extra steps.

 

I decided to put the view representation selection into a list, but it could be done with logic as long as the View names are consistent throughout all assemblies.

Message 14 of 33

andrew_canfield
Collaborator
Collaborator

Excellent - however my ability to find odd problems continues.

 

I've moved the code to an external rule folder & it works on the test assembly.

 

There was a 'real' assembly which was being looked at & this returns a message:

Terminating - Part * cannot be overwritten

* up to part 11 now -not sure if a Part11 exist's somewhere, very likely.

Testing continues 99.9% there 🙂

Working ok on a different test assembly..

0 Likes
Message 15 of 33

J-Camper
Advisor
Advisor

What you are seeing is the save attempt in the code:

Try
		NewDoc.SaveAs(FileName, False)
	Catch
		MessageBox.Show(NewDoc.DisplayName & " cannot be overwritten.", "Terminating")
		NewDoc.Close(True)
		Exit Sub
	End Try

It "Trys" to do a save as on the new open document we are building, "Part*".  When the "Try" fails the  "Catch" Triggers, where it says it can't be over written then closes the open document without saving. 

 

Was the part open in another tab? Or maybe it's checked out in the vault or set to read only?

0 Likes
Message 16 of 33

andrew_canfield
Collaborator
Collaborator

All good.

The part was already saved from an earlier test last week - thanks again.

0 Likes
Message 17 of 33

andrew_canfield
Collaborator
Collaborator
Still like this program 🙂
Wondering if a filter by size can be added?
So the Bounding Box is only applied to parts less than 200mm on the diagonal (value adjustable)
Regards

Andrew
0 Likes
Message 18 of 33

J-Camper
Advisor
Advisor

I wanted to reach out real quick.  I didn't look at the forum over the holidays and my area was hit with a major snow storm which has left me without power for several days on going.  I will look into this, as it should be possible, but I won't have time for a while longer.

 

If you want to look into this your self, my approach would be to take the Object Collection of Parts only and run it through another custom function to "Refine" the Object collection for bounding box size then pass the "Refined" Object Collection into the DerivedPartDefinition. This is where I think the "Refining" Function would go:

'Limit bounding box to part files only
	Dim partCol As ObjectCollection = GetOnlyParts(oDerivedAsmDef.Occurrences)
	
Dim RefinedpartCol As ObjectCollection = RefineParts(partCol, "200mm")

	For Each Oc As DerivedAssemblyOccurrence In RefinedpartCol
		Oc.InclusionOption = DerivedComponentOptionEnum.kDerivedBoundingBox
	Next

 

RefineParts(partCol, "200mm") would be a function that returns an Object Collection whose parts all have a bounding box dimension greater than 200mm.  In that function you would need to use bondingBox or OrientedBoundingBox to get corners you can pull a diagonal of.  For each part in the supplied collection you test and add to result if passes.

 

Again, I can look into this further after I get power restored and back to normal home life.  Someone else on the forum might be able to help before I get a chance to really dig in.

0 Likes
Message 19 of 33

andrew_canfield
Collaborator
Collaborator

Hello J

Hopefully you can dig you way out of the snow soon!

I'm pretty sure whenever you have chance to revisit this will be quicker than me trying to update the code - managed to break it already! (too many arguments?)

But if it does work it'd be amazing - why it's not an option already bemuses me - I see hiding parts will lighted a model but it's still useful to know there's something there.

Many thanks for the update.

 

Regards

 

Andrew

0 Likes
Message 20 of 33

J-Camper
Advisor
Advisor
Accepted solution

@andrew_canfield,

 

Try This and let me know if it is working as intended:

Sub Main
	If ThisApplication.ActiveDocumentType <> kAssemblyDocumentObject Then MessageBox.Show("This rule is designed to only work in assembly documents.", "Wrong Document Type") : Exit Sub
	'Main Setup:
	Dim AsmDoc As AssemblyDocument = ThisApplication.ActiveDocument
	Dim FileName As String = AsmDoc.FullFileName : FileName = Left(FileName, (FileName.Length-4)) & "_SUB" & ".ipt"
	
	'ViewRep Sample Setup:
	Dim RepID As String = ""
	Dim RepIDlist As New List(Of String)
	'Get List from file so we can choose view from list. This Can be automated with desired name
	For Each View In AsmDoc.ComponentDefinition.RepresentationsManager.DesignViewRepresentations
		RepIDlist.Add(View.Name)
	Next	

	'Temporarily choosing view from list. This can be automated with desired name
	RepID = InputListBox("Select a View Rep to derive", RepIDlist, RepIDlist.Item(0), Title := "View Representations", ListName := "Available:")
	If RepID = "" Then RepID = "Master" 'Setting a Default Value for nothing selected
	'Set View representation so visibility can be verified
	AsmDoc.ComponentDefinition.RepresentationsManager.DesignViewRepresentations.Item(RepID).Activate

	'New Document Setup:
	Dim NewDoc As PartDocument = ThisApplication.Documents.Add(DocumentTypeEnum.kPartDocumentObject, , False) 'include path to template file [if defualt is insufficient] between ,  , after DocumentTypeEnum.kPartDocumentObject
	Dim oDerivedAsmDef As DerivedAssemblyDefinition = NewDoc.ComponentDefinition.ReferenceComponents.DerivedAssemblyComponents.CreateDefinition(AsmDoc.FullFileName)

	'Derived Assembly Options:
	oDerivedAsmDef.ScaleFactor = 1
	oDerivedAsmDef.ReducedMemoryMode = True
	oDerivedAsmDef.UseColorOverridesFromSource = True
	oDerivedAsmDef.IncludeAllTopLeveliMateDefinitions = DerivedComponentOptionEnum.kDerivedExcludeAll
	oDerivedAsmDef.IncludeAllTopLevelParameters = DerivedComponentOptionEnum.kDerivedExcludeAll
	oDerivedAsmDef.IncludeAllTopLevelSketches = DerivedComponentOptionEnum.kDerivedExcludeAll
	oDerivedAsmDef.IncludeAllTopLevelWorkFeatures = DerivedComponentOptionEnum.kDerivedExcludeAll
	oDerivedAsmDef.DeriveStyle =  DerivedComponentStyleEnum.kDeriveAsSingleBodyNoSeams
	oDerivedAsmDef.InclusionOption = DerivedComponentOptionEnum.kDerivedExcludeAll
	oDerivedAsmDef.ActiveDesignViewRepresentation = RepID 'Where RepID is a string of the View rep name

	'Limit bounding box to part files only
	Dim partCol As ObjectCollection = GetOnlyParts(oDerivedAsmDef.Occurrences)
	
	'Limit bounding box to smaller than target
	Dim minLimit As Double = 20 'cm [internal units are cm]
	Dim RefinedpartCol As ObjectCollection = RefinePartsMin(partCol, minLimit)
	
	For Each Oc As DerivedAssemblyOccurrence In RefinedpartCol
		Oc.InclusionOption = DerivedComponentOptionEnum.kDerivedBoundingBox
	Next

	Call NewDoc.ComponentDefinition.ReferenceComponents.DerivedAssemblyComponents.Add(oDerivedAsmDef)

	Try
		NewDoc.SaveAs(FileName, False)
	Catch
		MessageBox.Show(NewDoc.DisplayName & " cannot be overwritten.", "Terminating")
		NewDoc.Close(True)
		Exit Sub
	End Try
	
	ThisApplication.Documents.Open(NewDoc.FullDocumentName, True)
	
End Sub

Function RefinePartsMin(mainCol As ObjectCollection, limit As Double) As ObjectCollection
	Dim Result As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection
	
	For Each Oc As DerivedAssemblyOccurrence In mainCol
		Dim oBox As Box = Oc.ReferencedOccurrence.RangeBox
		Dim diagonal As Vector = oBox.MinPoint.VectorTo(oBox.MaxPoint)
		If diagonal.Length <= limit Then Result.Add(Oc)
	Next
	
	Return Result
End Function

Function GetOnlyParts(mainCol As DerivedAssemblyOccurrences) As ObjectCollection
	Dim Result As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection
	
	For Each Oc As DerivedAssemblyOccurrence In mainCol
		
		If Oc.IsAssembly = False
			
			If Oc.ReferencedOccurrence.Suppressed = False And Oc.ReferencedOccurrence.Visible = True
				Result.Add(Oc)
			End If
		
		Else
			
			For Each OcSub As DerivedAssemblyOccurrence In GetOnlyParts(Oc.SubOccurrences)
				If OcSub.ReferencedOccurrence.Suppressed = False And OcSub.ReferencedOccurrence.Visible = True
					Result.Add(OcSub)
				End If
			Next
		
		End If
	Next
	
	Return Result
End Function

I added a function that limits the bounding box setting to parts that have a diagonal less than or equal to 20cm [internal units for API are in cm].

 

Let me know if you have any question or if this is not working as intended.