Announcements
Attention for Customers without Multi-Factor Authentication or Single Sign-On - OTP Verification rolls out April 2025. Read all about it here.

iLogic rule to find Duct Volume

bhavik4244
Collaborator

iLogic rule to find Duct Volume

bhavik4244
Collaborator
Collaborator

Hello,

 

I am trying to make a rule for measuring the duct volume. In the projects, we are having the duct in any route so my idea is to first make a simplified model and measure the inside volume.

 

the real challenge is to develop inside solid by selecting multiple faces. Please have a look at my screencast attached. 

 

I would like to have a rule which allows me to pick the inside faces of the duct and measure the inside volume for the same. (I think we might have to develop full solid inside. but I am not sure there could be some other way).

 

your help will be highly appreciated.

 

Thanks,

Bhavik Suthar

 

 

 

Bhavik Suthar
0 Likes
Reply
Accepted solutions (2)
1,057 Views
5 Replies
Replies (5)

J-Camper
Advisor
Advisor

I think there is an easy solution to this if the duct work will always be created with a shell feature, and you work with single solidbody parts.  If this is not the case then let me know.

Dim pDef As PartComponentDefinition = ThisDoc.Document.ComponentDefinition
Dim sb As SurfaceBody = pDef.SurfaceBodies.Item(1)

Dim Volume1 As Double = sb.Volume(0.0001)
Dim Volume2 As Double
Dim Volume3 As Double

Dim oShellFeat As ShellFeature

For Each oFeat As PartFeature In sb.AffectedByFeatures
	If oFeat.Type = ObjectTypeEnum.kShellFeatureObject
		oShellFeat = oFeat
		Exit For
	End If
Next

If IsNothing(oShellFeat) Then MessageBox.Show("Solid not affected by a shell feature", "Custom Error 1") : Exit Sub

Dim EOPmarkerCurrent As Object
Dim eopBefore As Object
Dim eopAfter As Object
pDef.GetEndOfPartPosition(eopAfter, eopBefore)
If IsNothing(eopAfter)
	EOPmarkerCurrent = eopBefore
Else
	EOPmarkerCurrent = eopAfter
End If

oShellFeat.SetEndOfPart(True)'Before = True After = False

Dim Tempsb As SurfaceBody = pDef.SurfaceBodies.Item(1)
Volume2 = Tempsb.Volume(0.0001)

'MessageBox.Show("Shell Volume [cm^3]: " & Round(Volume1, 5) & vbCrLf & "Void Volume [cm^3]: " & Round(Volume2, 5), "Volume Comparison:")

EOPmarkerCurrent.SetEndOfPart(False)'Before = True After = False

If oShellFeat.Definition.Direction = ShellDirectionEnum.kOutsideShellDirection
	Volume3 = Volume2
Else If oShellFeat.Definition.Direction = ShellDirectionEnum.kInsideShellDirection
	Volume3 = Volume2-Volume1
Else If oShellFeat.Definition.Direction = ShellDirectionEnum.kBothSidesShellDirection
	MessageBox.Show("It's not as easy to determine BothSidesShellDirection without more work.  If you use this type let me know and we can adapt this code.", "Option Not Programed")
	Exit Sub
End If

MessageBox.Show("Volume using Internal Units [cm^3]: " & Round(Volume3, 5) & vbCrLf & _
				"Volume converted Units [in^3]: " & Round((Volume3/(2.54^3)), 5), "Volume:")

It works by moving Checking current Volume, then moves EOP above the Shell Feature to read the second volume.  Then depending on the type of Shell direction it determines the void volume, and returns EOP to it's original position.  I do not have anything worked out for a shell feature going both directions as that is much more involved. 

 

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

bhavik4244
Collaborator
Collaborator

@J-Camper 

 

Thanks for the help, however it doesn't solve my sole purpose. Actually we have a long duct line installed in assembly, we just make shrinkwrap of duct installed in an assembly then we have to calculate the inside volume of the duct. it's even double work to do the whole assemblies duct feature again with shell involved in it.

 

Does it possible to select the faces, as I did in the screencast and it will generate an internal body and then we can measure the volume?

 

Again thanks for your tip.


Bhavik Suthar
0 Likes

J-Camper
Advisor
Advisor

Hmm... if you have a full duct system to check, you might not want to have to manually select all internal faces and you would have to close the open ends anyways in order for Inventor to give a Volume. 

 

I think you could use a workflow like this maybe:

- Read volume of existing solid

- copy the Solid Body temporarily with an array, as new body

- patch the open ends

- Sculpt the patches to the temporary solid (to fill void)

- Read the volume of this sculpted solid and subtract your original volume for final void volume

At this point you can delete the arrayed solid, pull EOP up above array, or leave it if the extra solid body doesn't bother you

 

Let me know if you have any questions or if this new workflow is unacceptable, and we can think of something else.

0 Likes

JelteDeJong
Mentor
Mentor
Accepted solution

Some time a go i wrote this blog post. Its about Comparing part geometry with iLogic. I figured if you fill all holes and then compare it with the original file you will get a part that is the inner volume. So i changed my original blog post. now it will give you a volume (as a part and as a message). The only down side is that it creates some extra files.  it starts by creating a assembly wit only the original part. That is assembly is used to create a simplified model and fill all holes. then my original code go's to work and creates a diff file.

Try it and let me know what you think..

 

Sub Main()
    Dim oTg As TransientGeometry = ThisApplication.TransientGeometry
    Dim doc As Document = ThisDoc.Document

    Dim ass As AssemblyDocument = ThisApplication.Documents.Add(DocumentTypeEnum.kAssemblyDocumentObject)
    ass.ComponentDefinition.Occurrences.Add(doc.FullFileName, oTg.CreateMatrix())

    Dim path As String = IO.Path.GetDirectoryName(doc.FullFileName)
    Dim filename As String = IO.Path.GetFileNameWithoutExtension(doc.FullFileName)
    filename = filename & ".iam"
    filename = IO.Path.Combine(path, filename)
    ass.SaveAs(filename, True)
    ass.Close(True)

    Dim doc2 As PartDocument = ThisApplication.Documents.Add(DocumentTypeEnum.kPartDocumentObject)

    Dim derivedDef As DerivedAssemblyDefinition = doc2.ComponentDefinition.ReferenceComponents.DerivedAssemblyComponents.CreateDefinition(filename)
    derivedDef.DeriveStyle = DerivedComponentStyleEnum.kDeriveAsSingleBodyNoSeams
    derivedDef.SetHolePatchingOptions(DerivedHolePatchEnum.kDerivedPatchAll)

    Dim derivedPart As DerivedAssemblyComponent = doc2.ComponentDefinition.ReferenceComponents.DerivedAssemblyComponents.Add(derivedDef)
    derivedPart.BreakLinkToFile()

    Dim filename2 As String = IO.Path.GetFileNameWithoutExtension(doc.FullFileName)
    filename2 = filename2 & "_closed.ipt"
    filename2 = IO.Path.Combine(path, filename2)
    doc2.SaveAs(filename2, True)
    doc2.Close(True)


    Dim partName1 As String = doc.FullFileName
    Dim partName2 As String = filename2

    Dim partDoc As PartDocument = createDiff(partName2, partName1)
    Dim massProps As MassProperties = partDoc.ComponentDefinition.MassProperties
    Dim uom As UnitsOfMeasure = partDoc.UnitsOfMeasure

    Dim defaultLength As String = uom.GetStringFromType(uom.LengthUnits)
    Dim volume As String = uom.GetStringFromValue(partDoc.ComponentDefinition.MassProperties.Volume, defaultLength & "^3")
    MsgBox(volume)
End Sub

Public Function createDiff(fileName1 As String, fileName2 As String) As PartDocument
    Dim doc As PartDocument = ThisApplication.Documents.Open(fileName1, True)
    Dim fileInfo As IO.FileInfo = New IO.FileInfo(doc.FullFileName)
    Dim newFileName = IO.Path.Combine(
        fileInfo.DirectoryName,
        fileInfo.Name.Replace(fileInfo.Extension, "") +
        "_dif" +
        fileInfo.Extension)
    doc.SaveAs(newFileName, False)


    Dim derivedPartDef As DerivedPartUniformScaleDef
    derivedPartDef = doc.ComponentDefinition.ReferenceComponents.DerivedPartComponents.CreateUniformScaleDef(fileName2)

    derivedPartDef.BodyAsSolidBody = False

    Dim derivedPart As DerivedPartComponent
    derivedPart = doc.ComponentDefinition.ReferenceComponents.DerivedPartComponents.Add(derivedPartDef)
    derivedPart.BreakLinkToFile()

    Dim splitTool As SurfaceBody = doc.ComponentDefinition.WorkSurfaces.Item(1)._SurfaceBody
    splitTool.Visible = False

    Dim body As SurfaceBody = doc.ComponentDefinition.SurfaceBodies.Item(1)
    Try
        doc.ComponentDefinition.Features.SplitFeatures.TrimSolid(splitTool, body, False)
    Catch ex As Exception
        doc.ComponentDefinition.Features.SplitFeatures.TrimSolid(splitTool, body, True)
    End Try
    Try
        doc.ActiveRenderStyle = doc.RenderStyles.Item("Green")
    Catch ex As Exception

    End Try

    ThisApplication.ActiveView.Update()

    'doc.Save()
    'doc.Close(True)
    Return doc
End Function

Jelte de Jong
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Blog: hjalte.nl - github.com

0 Likes

bhavik4244
Collaborator
Collaborator
Accepted solution

@JelteDeJong 

 

Thanks for your help, there was some issue in splitting geometry. However, I twisted it as per my requirement. Now it's working perfectly.

 

Here below code which I exactly used:

 

Sub Main()
    Dim oTg As TransientGeometry = ThisApplication.TransientGeometry
    Dim doc As Document = ThisDoc.Document

    Dim ass As AssemblyDocument = ThisApplication.Documents.Add(DocumentTypeEnum.kAssemblyDocumentObject)
    ass.ComponentDefinition.Occurrences.Add(doc.FullFileName, oTg.CreateMatrix())

    Dim path As String = IO.Path.GetDirectoryName(doc.FullFileName)
    Dim filename As String = IO.Path.GetFileNameWithoutExtension(doc.FullFileName)
    filename = filename & ".iam"
    filename = IO.Path.Combine(path, filename)
    ass.SaveAs(filename, True)
    ass.Close(True)

    Dim doc2 As PartDocument = ThisApplication.Documents.Add(DocumentTypeEnum.kPartDocumentObject)

    Dim derivedDef As DerivedAssemblyDefinition = doc2.ComponentDefinition.ReferenceComponents.DerivedAssemblyComponents.CreateDefinition(filename)
    derivedDef.DeriveStyle = DerivedComponentStyleEnum.kDeriveAsSingleBodyNoSeams
    derivedDef.SetHolePatchingOptions(DerivedHolePatchEnum.kDerivedPatchAll)

    Dim derivedPart As DerivedAssemblyComponent = doc2.ComponentDefinition.ReferenceComponents.DerivedAssemblyComponents.Add(derivedDef)


    Dim filename2 As String = IO.Path.GetFileNameWithoutExtension(doc.FullFileName)
    filename2 = filename2 & "_closed.ipt"
    filename2 = IO.Path.Combine(path, filename2)
    doc2.SaveAs(filename2, True)
    doc2.Close(True)


    Dim partName1 As String = doc.FullFileName
    Dim partName2 As String = filename2

    Dim partDoc As PartDocument = createDiff(partName2, partName1)
    Dim massProps As MassProperties = partDoc.ComponentDefinition.MassProperties
    Dim uom As UnitsOfMeasure = partDoc.UnitsOfMeasure

    Dim defaultLength As String = uom.GetStringFromType(uom.LengthUnits)
    Dim volume As String = uom.GetStringFromValue(partDoc.ComponentDefinition.MassProperties.Volume, defaultLength & "^3")
    MsgBox(volume)
End Sub

Public Function createDiff(fileName1 As String, fileName2 As String) As PartDocument
    Dim doc As PartDocument = ThisApplication.Documents.Open(fileName1, True)
    Dim fileInfo As IO.FileInfo = New IO.FileInfo(doc.FullFileName)
    Dim newFileName = IO.Path.Combine(
        fileInfo.DirectoryName,
        fileInfo.Name.Replace(fileInfo.Extension, "") +
        "_dif" +
        fileInfo.Extension)
    doc.SaveAs(newFileName, False)


    Dim derivedPartDef As DerivedPartUniformScaleDef
    derivedPartDef = doc.ComponentDefinition.ReferenceComponents.DerivedPartComponents.CreateUniformScaleDef(fileName2)

    derivedPartDef.BodyAsSolidBody = True

    Dim derivedPart As DerivedPartComponent
    derivedPart = doc.ComponentDefinition.ReferenceComponents.DerivedPartComponents.Add(derivedPartDef)

'create a collection 
	Dim oColl As ObjectCollection
    oColl = ThisApplication.TransientObjects.CreateObjectCollection
	
    Dim splitTool As SurfaceBody = doc.ComponentDefinition.SurfaceBodies.Item(2)
    oColl.Add(splitTool)
	splitTool.Visible = False

    Dim body As SurfaceBody = doc.ComponentDefinition.SurfaceBodies.Item(1)
	    Try
	doc.ComponentDefinition.Features.CombineFeatures.Add(body, oColl,PartFeatureOperationEnum.kCutOperation, )
	 Catch
		End Try
		doc.ActiveRenderStyle = doc.RenderStyles.Item("Green")


    ThisApplication.ActiveView.Update()

    Return doc
End Function

 


Bhavik Suthar
0 Likes