check if Box intersects SurfaceBody

check if Box intersects SurfaceBody

J.Pelfrene
Enthusiast Enthusiast
965 Views
8 Replies
Message 1 of 9

check if Box intersects SurfaceBody

J.Pelfrene
Enthusiast
Enthusiast

Hi,

 

Would there be an efficient method to check if a Box object (or OrientedBox) contains any material of a SurfaceBody? Or even specific Faces / Edges of a SurfaceBody

 

I could think of checking for all the Vertices of the SurfaceBody whether they are in the Box. But that can be quite costly and also would give the wrong solution if the Box intersects some Faces, but not containing the Vertices.

 

Thanks,

Joren

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

dalton98
Collaborator
Collaborator

If I'm understanding correctly you want to get the edge, face, and vertex values when you click and drag a select box over your part? Sadly I don't think this is possible. You can test the number of objects selected, but if you highlight the entire part it will only return the faces, not the edges and vertices.

Dim oDoc As PartDocument
oDoc = ThisApplication.ActiveDocument

MessageBox.Show(oDoc.SelectSet.Count)

MessageBox.Show(oDoc.SelectSet.Item(1).Parent.Name)    

 

0 Likes
Message 3 of 9

J.Pelfrene
Enthusiast
Enthusiast

Thanks for your answer.

I didn't intend it that way, although that could also be a useful check.

What I need is to check if there is any material present in a certain zone, as defined by a Box object. Something like:

Public Sub Main()
    Dim oDoc As PartDocument = ThisApplication.ActiveDocument
    Dim oTG As TransientGeometry = ThisApplication.TransientGeometry 
    Dim oSBodies As SurfaceBodies = oDoc.ComponentDefinition.SurfaceBodies 
    Dim oSBody As SurfaceBody

    Dim oBox As Box = oTG.CreateBox()
    oBox.MinPoint = oTG.CreatePoint(0., 0., 0.)
    oBox.MaxPoint = oTG.CreatePoint(1., 1., 1.)

    Dim hasMaterial As Boolean = False
    For Each oSBody In oSBodies
        hasMaterial = hasMaterial Or checkIfMaterialIsInBox(oBox, oSBody)
    Next

    If hasMaterial Then
        MsgBox("Box contains material")
    Else
        MsgBox("Box does not contain material")
    End If

End Sub

Private Function checkIfMaterialIsInBox(ByVal oBox As Box, ByVal oSBody As SurfaceBody) As Boolean
    ...
   
End Function

 

Then would it be possible to write such a function 'checkIfMaterialIsInBox' ? 

0 Likes
Message 4 of 9

WCrihfield
Mentor
Mentor

Is this in the context of a part document or an assembly?  If a part, is it a multi-body part?  Did you know that the SurfaceBody object also has a IsPointInside property?  This is definitely a complicated task to automate.  In an assembly, you can check for interference between components, but it's not as easy within a part environment, because it is not an expected necessity.  I have seen some folks use the MeasureTools.GetMinimumDistance method, with its optional 'Context' (NameValueMap) settings to help determine if two 3D surfaces intersect with each other before.  Here is a similar example.  Also seems like I have seen others use the BREP system along with tools like the combine command (performs boolean type tasks like Cut, Join, & Intersect), to check if two bodies intersect each other.  It may require more code & complication than you were hoping for, but may be less 'expensive' to check that way.  I don't recall having a ready-made solution for this situation on hand though.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 5 of 9

J.Pelfrene
Enthusiast
Enthusiast

Thanks!

Yeah, that helps.

 

Yes, it's in the Part level. I want to automatically check if a certain hole can be manufactured and need to know if enough space is left for the tool. 

One way could be:

1. check if the cornerpoints of the box are in the body with IsPointInside

2. If not: check if the box planes intersect with any of the body surfaces like in the example from the linked post.

 

That would work, but it's going to be slow. Meanwhile trying to think of a more efficient way to do it. Perhaps Boolean operations (Intersect) can help there. But I presume it is then necessary to really create the box as a body in the Part drawing, do the Intersect and then undo again. It would be preferable not to do that as I want to check the drawing, but not modify it.

 

If I find an elegant way, I'll post it. And of course still open for suggestions 🙂

0 Likes
Message 6 of 9

WCrihfield
Mentor
Mentor
Accepted solution

Here is one of the BREP checks I was thinking about.  It's actually a bit quicker and cleaner than I had pictured in my head.  I'm not sure if this would 'dirty' the model or not, since it is just doing 'transient BREP' stuff.  But my guess is that it will not dirty the model because running this does not make any actual changes to the existing model or geometry, and does not leave anything to 'UNDO' in the undo list.

Sub Main
	Dim oBody1 As SurfaceBody = PickSurfaceBody
	Dim oBody2 As SurfaceBody = PickSurfaceBody
	Dim oOverlap As Boolean = SurfaceBodiesIntersect(oBody1, oBody2)
	MsgBox("oOverlap = " & oOverlap,,"")
End Sub

Function PickSurfaceBody(Optional oPrompt As String = vbNullString) As SurfaceBody
	If oPrompt = "" Then oPrompt = "Select a SurfaceBody."
	oObj = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kPartBodyFilter, oPrompt)
	If IsNothing(oObj) OrElse (TypeOf oObj Is SurfaceBody = False) Then Return Nothing
	Dim oBody As SurfaceBody = oObj
	Return oBody
End Function

Function SurfaceBodiesIntersect(oBody1 As SurfaceBody, oBody2 As SurfaceBody) As Boolean
	If IsNothing(oBody1) Or IsNothing(oBody2) Then Return False
	Dim oVolChange As Boolean = False
	oVol1 = oBody1.Volume(0.0001)
	Dim oTBrep As TransientBRep = ThisApplication.TransientBRep
	Dim oBody1Copy As SurfaceBody = oTBrep.Copy(oBody1)
	Try
		oTBrep.DoBoolean(oBody1Copy, oBody2, BooleanTypeEnum.kBooleanTypeDifference)
	Catch oEx As Exception
		MsgBox(oEx.Message & vbCrLf & oEx.StackTrace, vbExclamation, "")
		'Logger.Error(oEx.Message & vbCrLf & oEx.StackTrace)
		Return False
	End Try
	If oBody1Copy.Volume(0.0001) <> oVol1 Then Return True
End Function

This will only catch if the two bodies overlapped enough to result in a measurable amount of shared volume.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 7 of 9

J.Pelfrene
Enthusiast
Enthusiast

Oh, that looks great. I haven't explored the possibilities of transient BRep so far, but I see it can help me in more ways.

The transient body could be made with TransientBRep.CreateSolidBlock 

 

I will try this in the coming days. Thanks again.

0 Likes
Message 8 of 9

J.Pelfrene
Enthusiast
Enthusiast

I'm using this method in my add-in and it works fine for most files.

But now I have some parts where I get a wrong result.

 

2022-06-15 10_50_58-Autodesk Inventor Professional 2021.png

 This results in a overlap!

 

So the grey part is an extruded profile with holes (such as the one highlighted in blue). The yellow box is created below one of those holes and we want to check if this space is empty (accessible for tools). I already apply a small offset of 0.1mm from the hole and it is clear to see that there is no intersection.

 

With offset of 0.1mm I get these results:

- box volume before Boolean: 0.14104 

- box volume after Boolean: 0 --> this would mean that the entire box overlaps with the part body

 

Increasing the offset from the hole to 0.6mm I do get a valid result:

- box volume before Boolean: 0.12464

- box volume after Boolean: 0.12464

 

Any idea how this could happen?

It only occurs for this range of similar .ipt-files, but it's important that results from this check are consistent.

0 Likes
Message 9 of 9

J.Pelfrene
Enthusiast
Enthusiast

Macro for checking:

 

Public Sub checkBoxOverlap()
    Dim oDoc As PartDocument
    Set oDoc = ThisApplication.ActiveDocument
    Dim oTG As TransientGeometry
    Set oTG = ThisApplication.TransientGeometry
    Dim oTransientBRep As TransientBRep
    Set oTransientBRep = ThisApplication.TransientBRep
    Dim oCompDef As PartComponentDefinition
    Set oCompDef = oDoc.ComponentDefinition
    Dim oSBodies As SurfaceBodies
    Set oSBodies = oCompDef.SurfaceBodies

    Dim pmin As Point
    Dim pmax As Point
    Set pmin = oTG.CreatePoint(4.89, 0.71, 2.02)
    Set pmax = oTG.CreatePoint(5.32, 1.53, 2.42)
    
    Dim oBox As box
    Set oBox = oTG.CreateBox()
    oBox.MinPoint = pmin
    oBox.MaxPoint = pmax
    
    Dim oBoxBody As SurfaceBody
    Set oBoxBody = oTransientBRep.CreateSolidBlock(oBox)
    
    Dim oBaseFeature As NonParametricBaseFeature
    Set oBaseFeature = oCompDef.Features.NonParametricBaseFeatures.Add(oBoxBody)
    
    'Check if intersect
    Dim oSBody As SurfaceBody
    For Each oSBody In oSBodies
        Dim oVol1 As Double
        oVol1 = oBoxBody.Volume(0.0001)
        Debug.Print (oVol1)
        Call oTransientBRep.DoBoolean(oBoxBody, oSBody, BooleanTypeEnum.kBooleanTypeDifference)
        Dim oVol2 As Double
        oVol2 = oBoxBody.Volume(0.0001)
        Debug.Print (oVol2)
        Debug.Print ("Box space empty: " & (oVol1 = oVol2))
    Next
        
End Sub
0 Likes