Can iLogic calculate the volumes of two solids within a single part file?

Can iLogic calculate the volumes of two solids within a single part file?

chris
Advisor Advisor
926 Views
13 Replies
Message 1 of 14

Can iLogic calculate the volumes of two solids within a single part file?

chris
Advisor
Advisor

Can iLogic calculate the individual volumes of each solid in a multibody part file?

Also, I know I can use iLogic to give the extents of a sheet metal part, but can it do the same for a regular part file? (Length, Width, and height)

0 Likes
Accepted solutions (2)
927 Views
13 Replies
Replies (13)
Message 2 of 14

J-Camper
Advisor
Advisor

@chris,

Here is an example of what you are asking for:

Sub Main

	Dim pDoc As PartDocument = TryCast(ThisApplication.ActiveDocument, PartDocument)
	If IsNothing(pDoc) Then Logger.Debug("Not Run In Part Document") : Exit Sub
	
	For Each sb As SurfaceBody In pDoc.ComponentDefinition.SurfaceBodies
		If Not sb.IsSolid Then Continue For
		Dim sbVolume As Double = sb.Volume(.0001)
		Logger.Trace(String.Format("{0} = {1} cm^3",sb.Name, sbVolume))
	Next

	Call AlignedBoxSize(pDoc.ComponentDefinition.PreciseRangeBox)'Box aligned with origin
	Call OrientedBoxSize(pDoc.ComponentDefinition.OrientedMinimumRangeBox)'Box allowed to rotate for tightest fit
	
End Sub

Sub AlignedBoxSize(aRangeBox As Box)
	Dim xLength, yLength, zLength As Double
	xLength = aRangeBox.MaxPoint.X - aRangeBox.MinPoint.X
	yLength = aRangeBox.MaxPoint.Y - aRangeBox.MinPoint.Y
	zLength = aRangeBox.MaxPoint.Z - aRangeBox.MinPoint.Z 
	Logger.Trace(String.Format("X: {0} cm, Y: {1} cm, Z: {2} cm",xLength, yLength, zLength))
End Sub

Sub OrientedBoxSize(anOrientedBox As OrientedBox)
	Dim SizeOfBox As New List(Of Double)
	SizeOfBox.Add(anOrientedBox.DirectionOne.Length)
	SizeOfBox.Add(anOrientedBox.DirectionTwo.Length)
	SizeOfBox.Add(anOrientedBox.DirectionThree.Length)
	SizeOfBox.Sort()
	Logger.Trace(String.Format("Min Length: {0} cm, Mid Length: {1} cm, Max Length: {2} cm",SizeOfBox.Item(0), SizeOfBox.Item(1), SizeOfBox.Item(2)))
End Sub

 

I don't think there is a simple extents property for normal parts, but you can get a range box or oriented range box, which are both shown in above iLogic.

0 Likes
Message 3 of 14

chris
Advisor
Advisor

@J-Camper  Thank you, but is there a way to export the values? For example, can the logic write all this to custom parameters as well as the volumes in cubic inches?

0 Likes
Message 4 of 14

chris
Advisor
Advisor

If it can't map them to parameters, how do/can I access them?

 

0 Likes
Message 5 of 14

chris
Advisor
Advisor

@J-Camper what is a "logger Trace", I have never seen that before?

0 Likes
Message 6 of 14

Michael.Navara
Advisor
Advisor

When you have a value of volume, you can do whatever you want. You can write it to the parameter for example. Parameter with the name 'parVolume' must exists. If you set the parameter property Value, the value must be in database units. Then you can set the units of the parameter to inches and its value is converted automatically.

 

 

Dim pDoc As PartDocument = ThisDoc.Document
'...
Dim sbVolume As Double = 1 'sb.Volume(.0001)
'...
pDoc.ComponentDefinition.Parameters("parVolume").Value = sbVolume

 

MichaelNavara_0-1717740253210.png

 

Logger.Trace is one of several methods which write message to iLogic log window. Trace is the lowest level.

MichaelNavara_0-1717739915469.png

 

0 Likes
Message 7 of 14

chris
Advisor
Advisor

@Michael.Navara apologies for not understanding... firstly, in your above example, am I adding the code you wrote below the code that @J-Camper wrote? Second, how are you getting the in^3 as a unit type, I can't find that?

I know I'm missing something, I just don't entirely understand what @J-Camper wrote or what you added.

0 Likes
Message 8 of 14

Michael.Navara
Advisor
Advisor
Accepted solution

Units: If you want to use parameter, you must specify the units. If the parameter is calculated by expression (for example Area = Length * Width) you must specify appropriate units otherwise Inventor show an error. For example you can write in * in to the units field in parameter definition and this is automatically converted to in^2. The same works for volume.

MichaelNavara_0-1717759411613.png

 

Volume in parameter: You can use this modification for the code mentioned above. Only the part for volume remains.

Sub Main()

    Dim pDoc As PartDocument = TryCast(ThisApplication.ActiveDocument, PartDocument)
    If IsNothing(pDoc) Then Logger.Debug("Not Run In Part Document") : Exit Sub

    For Each sb As SurfaceBody In pDoc.ComponentDefinition.SurfaceBodies
        If Not sb.IsSolid Then Continue For
        Dim sbVolume As Double = sb.Volume(0.0001)
        Logger.Trace(String.Format("{0} = {1} cm^3", sb.Name, sbVolume))

        Dim paramName As String = sb.Name & "_Volume"
        Try
            pDoc.ComponentDefinition.Parameters.UserParameters(paramName).Value = sbVolume
        Catch ex As Exception
            pDoc.ComponentDefinition.Parameters.UserParameters.AddByValue(paramName, sbVolume, "in^3")
        End Try
    Next

    'Call AlignedBoxSize(pDoc.ComponentDefinition.PreciseRangeBox)'Box aligned with origin
    'Call OrientedBoxSize(pDoc.ComponentDefinition.OrientedMinimumRangeBox)'Box allowed to rotate for tightest fit

End Sub

 

0 Likes
Message 9 of 14

J-Camper
Advisor
Advisor
Accepted solution

@chris,

The "Logger.Trace" is a way to write a message in the iLogic Logger.  I prefer this over messageboxes for testing as you do not have to clear each messagebox, but it will still give you a look at each step.  In order to use it, you need to set log level to trace and have the iLogic Log window open:
Settings in ilogic windowSettings in ilogic windowresultsresults

 

Then For changing units you will need to do your own unit conversion for volume as the conversions from UnitsOfMeasure will not work for compound units.  I added the conversions to the rule I posted before:

Sub Main

	Dim pDoc As PartDocument = TryCast(ThisApplication.ActiveDocument, PartDocument)
	If IsNothing(pDoc) Then Logger.Debug("Not Run In Part Document") : Exit Sub
	
	For Each sb As SurfaceBody In pDoc.ComponentDefinition.SurfaceBodies
		If Not sb.IsSolid Then Continue For
		Dim sbVolume As Double = sb.Volume(.0001)
'		Logger.Trace(String.Format("{0} = {1} cm^3", sb.Name, sbVolume))
		sbVolume/=2.54^3 'cm are the database units, so cm^3 to in^3 conversion
		Logger.Trace(String.Format("{0} = {1} in^3", sb.Name, sbVolume))
	Next

	Call AlignedBoxSize(pDoc.ComponentDefinition.PreciseRangeBox)'Box aligned with origin
	Call OrientedBoxSize(pDoc.ComponentDefinition.OrientedMinimumRangeBox)'Box allowed to rotate for tightest fit
	
End Sub

Sub AlignedBoxSize(aRangeBox As Box)
	Dim xLength, yLength, zLength As Double
	xLength = aRangeBox.MaxPoint.X - aRangeBox.MinPoint.X
	yLength = aRangeBox.MaxPoint.Y - aRangeBox.MinPoint.Y
	zLength = aRangeBox.MaxPoint.Z - aRangeBox.MinPoint.Z 
'	Logger.Trace(String.Format("X: {0} cm, Y: {1} cm, Z: {2} cm", xLength, yLength, zLength))
	xLength /= 2.54 'cm are the database units, so cm to in conversion
	yLength /= 2.54 'cm are the database units, so cm to in conversion
	zLength /= 2.54 'cm are the database units, so cm to in conversion
	Logger.Trace(String.Format("X: {0} in, Y: {1} in, Z: {2} in", xLength, yLength, zLength))
	
End Sub

Sub OrientedBoxSize(anOrientedBox As OrientedBox)
	Dim SizeOfBox As New List(Of Double)
	SizeOfBox.Add(anOrientedBox.DirectionOne.Length)
	SizeOfBox.Add(anOrientedBox.DirectionTwo.Length)
	SizeOfBox.Add(anOrientedBox.DirectionThree.Length)
	SizeOfBox.Sort()
'	Logger.Trace(String.Format("Min Length: {0} cm, Mid Length: {1} cm, Max Length: {2} cm",SizeOfBox.Item(0), SizeOfBox.Item(1), SizeOfBox.Item(2)))
	SizeOfBox.Item(0) /= 2.54 'cm are the database units, so cm to in conversion
	SizeOfBox.Item(1) /= 2.54 'cm are the database units, so cm to in conversion
	SizeOfBox.Item(2) /= 2.54 'cm are the database units, so cm to in conversion
	Logger.Trace(String.Format("Min Length: {0} in, Mid Length: {1} in, Max Length: {2} in",SizeOfBox.Item(0), SizeOfBox.Item(1), SizeOfBox.Item(2)))
End Sub

Note that you could perform the conversion at the same time as you are setting initial values, but I left both the original and new traces available by separating the operations.

0 Likes
Message 10 of 14

Michael.Navara
Advisor
Advisor

For conversion square or cubic units you can use internal conversion using UnitsOfMeasure.ConvertUnits

Dim l1 As Double = 2.54 '1 in => cm
Dim l2 As Double = 2.54 '1 in => cm
Dim l3 As Double = 2.54 '1 in => cm

Dim v1 = l1 * l2 * l3
Logger.Debug(v1 & " cm3")

Dim v2 = ThisApplication.UnitsOfMeasure.ConvertUnits(v1, "cm^3", "in^3")
Logger.Debug(v2 & " in3") 'Expected 1 in^3

  

0 Likes
Message 11 of 14

chris
Advisor
Advisor

@J-Camper @Michael.Navara Thank you both for your help. I don't fully understand "how/why" you wrote what you did, but it's working for what I need!

0 Likes
Message 12 of 14

J-Camper
Advisor
Advisor

@Michael.Navara,

Thanks for the correction.  I usually try to stick with UnitsTypeEnum values instead of strings of units, but I do see that it works with strings.

0 Likes
Message 13 of 14

chris
Advisor
Advisor

what is the correct code to add to the volumes that will format the numbers to only be (one) decimal place?

 

Update: I figured out how to control the decimal places, but it only works in the "Logger" the Parameters and Form still show 5 or 6 decimal places...?

0 Likes
Message 14 of 14

J-Camper
Advisor
Advisor

@chris,

 

You should be able to put the Double into "Math.Round(Double Variable, 1)" The second item is how many decimal places:

 

Dim test As Double = 1.123456789
test = Math.Round(test, 1)
Logger.Trace(test)

 

Edit: If you are still getting weird results when setting the Parameter value, you can feed the Double in as a String:

Dim test As Double = 1.123456789
test = Math.Round(test, 1)
Logger.Trace(test)

Parameter("feedtest") = test.ToString

 

0 Likes