Multibody surface area

STECORO
Participant
Participant

Multibody surface area

STECORO
Participant
Participant

Hello Autodesk Community!

 

In order to improve the manufacturing process, I need to insert the painted surface area into the drawings.
I have found some code hints but I am missing a piece of the puzzle.


At the moment I can declare a colour and find its surface and then write it into a parameter, but this only happens for one solid.

My goal is to detect all colours other than (e.g. steel and polished steel), so that I am not limited to always declaring a specific colour for painting, but can use all of them except those I decide on.


Then i need to repeat this instruction for all the bodies and create and save everything within a parameter.

 

Thank you to anyone who can help me.

 

 

For Each oFace In ThisApplication.ActiveDocument.ComponentDefinition.Surfacebodies.item(1).Faces

oColor = oFace.getrenderstyle(StyleSourceTypeEnum.kOverrideRenderStyle)
'Declare the color If oColor.Name = "Orange" Then Painted_Area = Area+oFace.Evaluator.Area End If Next PAINTED_AREA = CStr(Painted_Area * 100)

 

0 Likes
Reply
Accepted solutions (1)
287 Views
6 Replies
Replies (6)

WCrihfield
Mentor
Mentor

Hi @STECORO.  Maybe this similar example will work better for you.  It includes the use of a 'List(Of String)' type variable, to hold the names of the colors/appearances that you do not want to include as painted area.  Alternately, you could use the same strategy to only find faces that are set to specific colors, using 'ColorsToInclude' type list, instead of 'ColorsToExclude' list.  It iterates all bodies, and all faces of each body.  But this example uses newer properties / objects / methods.  The 'render style' objects have been obsolete since around 2013 (see link below for more details about that).

Consistent Materials (Materials and Appearances) 

Sub Main
	Dim oPDoc As PartDocument = TryCast(ThisDoc.Document, Inventor.PartDocument)
	If oPDoc Is Nothing Then Return
	Dim oColorsToExclude As New List(Of String)
	oColorsToExclude.Add("Steel")
	oColorsToExclude.Add("Polished Steel")
'	Dim oColorsToInclude As New List(Of String)
'	oColorsToInclude.Add("Orange")
	Dim dPaintedArea As Double = 0.0
	For Each oBody As SurfaceBody In oPDoc.ComponentDefinition.SurfaceBodies
		For Each oFace As Face In oBody.Faces
			Dim sFaceAppearanceName As String = oFace.Appearance.DisplayName
			If oColorsToExclude.Contains(sFaceAppearanceName) Then Continue For
			Dim dArea As Double = oFace.Evaluator.Area
			dPaintedArea += dArea
		Next oFace
	Next oBody
	Parameter.Value("PAINTED_AREA") = CStr(dPaintedArea * 100)
	oPDoc.Update2(True)
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)

STECORO
Participant
Participant

Hi Wesley,
Thank you very much for your reply, it works correctly, but to be honest I forgot one detail that I think can close the macro.

When I have two or more solids , if I colour the surface the interference between the two solids will be calculated.
I saw an old article that talked about this issue (see below).

https://adndevblog.typepad.com/manufacturing/2015/12/inventor-api-volume-and-surface-area-of-the-mul...

Do you think it is possible to implement ilogic?

Thanks again

0 Likes

WCrihfield
Mentor
Mentor

Hi @STECORO.  Sure.  Here is a modified version of the first code I posted here, which includes the requested TransientBRep manipulations.  If the part only has one body, it will process that one body without this extra process, but if it has multiple bodies, it will create a new transient body that is a combined union of all bodies, then process that transient body instead.  I just finished typing this up for you, so I have not tested it yet.  Let me know how it works for you.

Sub Main
	Dim oPDoc As PartDocument = TryCast(ThisDoc.Document, Inventor.PartDocument)
	If oPDoc Is Nothing Then Return
	Dim oPDef As PartComponentDefinition = oPDoc.ComponentDefinition
	Dim oBodies As SurfaceBodies = oPDef.SurfaceBodies
	If oBodies.Count = 0 Then Return
	Dim oColorsToExclude As New List(Of String)
	oColorsToExclude.Add("Steel")
	oColorsToExclude.Add("Polished Steel")
	Dim oTBody As SurfaceBody = Nothing
	If Not oPDef.HasMultipleSolidBodies Then
		oTBody = oBodies.Item(1)
	Else
		Dim oTBRep As TransientBRep = ThisApplication.TransientBRep
		Dim oFirstBody, oBodyToBeModified, oToolBody As SurfaceBody
		oFirstBody = oBodies.Item(1)
		oBodyToBeModified = oTBRep.Copy(oFirstBody)
		For i As Integer = 1 To oBodies.Count
			oBody = oBodies.Item(i)
			If oBody Is oFirstBody Then Continue For
			oToolBody = oTBRep.Copy(oBody)
			oTBRep.DoBoolean(oBodyToBeModified, oToolBody, BooleanTypeEnum.kBooleanTypeUnion)
		Next i
		oTBody = oBodyToBeModified
	End If
	Dim dPaintedArea As Double = 0.0
	For Each oFace As Face In oTBody.Faces
		Dim sFaceAppearanceName As String = oFace.Appearance.DisplayName
		If oColorsToExclude.Contains(sFaceAppearanceName) Then Continue For
		Dim dArea As Double = oFace.Evaluator.Area
		dPaintedArea += dArea
	Next oFace
	Parameter.Value("PAINTED_AREA") = CStr(dPaintedArea * 100)
	oPDoc.Update2(True)
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)

0 Likes

STECORO
Participant
Participant

Hi Wesley, I tried but it doesn't work.
If I keep a single body it works fine, when I create the multibody it gives an error on row 28.

 

Thank you in advance for your kind support.

0 Likes

WCrihfield
Mentor
Mentor
Accepted solution

Hi @STECORO.  It seems as though the faces of copied 'transient' bodies do not retain the 'appearances' of the original, real bodies, and attempting to access them causes an error.  So, the next alternative is to use 'real' geometry techniques similar to the BRep Boolean operation to combine all bodies into one (temporarily), then check face appearances and areas, then 'UNDO' the feature that combined all the bodies again.  Below is an example iLogic code doing it that way, utilizing an Inventor.Transaction so that we can 'UNDO' the actions it is doing, and also utilizing a CombineFeature to join all bodies together.

Sub Main
	Dim oInvApp As Inventor.Application = ThisApplication
	Dim oPDoc As PartDocument = TryCast(ThisDoc.Document, Inventor.PartDocument)
	If oPDoc Is Nothing Then Return
	Dim oPDef As PartComponentDefinition = oPDoc.ComponentDefinition
	Dim oBodies As SurfaceBodies = oPDef.SurfaceBodies
	If oBodies.Count = 0 Then Return
	Dim oColorsToExclude As New List(Of String)
	oColorsToExclude.Add("Steel")
	oColorsToExclude.Add("Polished Steel")
	Dim oTBody As SurfaceBody = oBodies.Item(1)
	Dim dPaintedArea As Double = 0.0
	If Not oPDef.HasMultipleSolidBodies Then
		dPaintedArea = GetPaintedArea(oTBody, oColorsToExclude)
	ElseIf oPDef.HasMultipleSolidBodies Then
		Dim oTrans As Inventor.Transaction = oInvApp.TransactionManager.StartTransaction(oPDoc, "Combine Bodies - iLogic")
		Dim oCFs As CombineFeatures = oPDef.Features.CombineFeatures
		Dim oToolBodies As ObjectCollection = oInvApp.TransientObjects.CreateObjectCollection
		For i As Integer = 1 To oBodies.Count
			oBody = oBodies.Item(i)
			If oBody Is oTBody Then Continue For
			oToolBodies.Add(oBody)
		Next i
		Dim oCF As CombineFeature = oCFs.Add(oTBody, oToolBodies, PartFeatureOperationEnum.kJoinOperation, False)
		dPaintedArea = GetPaintedArea(oTBody, oColorsToExclude)
		oTrans.Abort
	End If
	iLogicVb.Automation.ParamValue(oPDoc, "PAINTED_AREA") = CStr(dPaintedArea * 100)
	oPDoc.Update2(True)
End Sub

Function GetPaintedArea(oBody As SurfaceBody, oAppearancesToExclude As List(Of String)) As Double
	If oBody Is Nothing OrElse oAppearancesToExclude Is Nothing OrElse oAppearancesToExclude.Count = 0 Then Exit Function
	Dim dPaintedArea As Double = 0.0
	For Each oFace As Face In oBody.Faces
		Dim sFaceAppearanceName As String = oFace.Appearance.DisplayName
		If oAppearancesToExclude.Contains(sFaceAppearanceName) Then Continue For
		Dim dArea As Double = oFace.Evaluator.Area
		dPaintedArea += dArea
	Next oFace
	Return dPaintedArea
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)

STECORO
Participant
Participant
Hi Wesley,
I wanted to thank you sincerely for your valuable help with the problem I had reported. Thanks to your contribution, not only was I able to solve it, but I was also able to implement a solution that greatly improved our manufacturing process.

Your expertise and helpfulness had a positive impact on the whole team, and I can only be grateful to you for sharing your experience.

Many thanks again!
Kind regards,

Stefano
0 Likes