Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

  • Congratulations waross on being selected by the Eng-Tips community for having the most helpful posts in the forums last week. Way to Go!

CATIA VBA break parts of disconnected body into separate bodies 3

Status
Not open for further replies.

samo_

Mechanical
Jun 19, 2020
5
US
My code splits a body with a plane. What results is a body made of two pieces. I need to separate these two pieces in code but I dont know how to do this.

What I am looking to do is split the body into two bodies (in VBA) so that I can continue to work with the two pieces separately.
The way I would do this manually is to copy and paste the body and use remove lump to isolate one part and then paste and remove the other lump. The problem I am running into when trying to implement this in VBA is that in order to use "remove lump" you need to select a face and I don't know how to tell which faces are part of the first piece and which are part of the second piece using only VBA (there seems to be nothing distinguishing them as being part of one closed piece versus the other).

The first picture shows the body before the split. The second picture shows the body after it has been split. Both solid pieces are part of the same body.

disconnected_body_2_pfrrfr.png

disconnected_body_rsx8p3.png


thanks,
Sam
 
Replies continue below

Recommended for you

Is there any way to break apart a body into separate bodies that anyone knows about?

Does anyone have any other ideas about how to do it manually? This might be a good place to start.
 
Thank you for your reply! That is not exactly my problem. Let me see if I can clarify.

I start with a single body pictured in my first post.
I split the body with a plane and select the side to keep.
The result of the split looks like this (and is a single body)
cut_Body_resultant_ssz81a.png


I want to separate these two chunks into different bodies similar to what you would do with "remove lump", but I want to do it in VBA.

Does that help clarify?
 
Hi Sam , i am not an expert but you can try this :

Sub CATMain()

Dim partDocument1 As PartDocument
Set partDocument1 = CATIA.ActiveDocument

Dim part1 As Part
Set part1 = partDocument1.Part

Dim bodies1 As Bodies
Set bodies1 = part1.Bodies

Dim body1 As Body
Set body1 = bodies1.Item("PartBody")

part1.InWorkObject = body1

Dim shapeFactory1 As ShapeFactory
Set shapeFactory1 = part1.ShapeFactory

Dim trim1 As Trim
Set trim1 = shapeFactory1.AddNewTrim(body1)

Dim shapes1 As Shapes
Set shapes1 = body1.Shapes

Dim remove1 As Remove
Set remove1 = shapes1.Item("Remove.1")

Dim EnabledObjectSelection1(0)
EnabledObjectSelection1(0) = "Face"
Dim osel2 As Object
Set osel2 = partDocument1.Selection
Dim status2 As String

MsgBox "Select the face to remove!"

status2 = osel2.SelectElement2(EnabledObjectSelection1, "Select face ", False)
If status2 = "Normal" And osel2.Count = 1 Then

Dim face1 As Face
Set face1 = osel2.Item(1).Value

End If

trim1.AddFaceToRemove face1

part1.Update

End Sub
 
TudorM thank you, that is very helpful. The code you provided can be used to separate the body into two parts, which solves the first part of the problem.

The remaining - and perhaps hardest part - of the problem is that this is part of a program that needs to loop many times, so I would like to automate the face selection for the split.
The other complication is that, in the example I gave, we have a body consisting of two chunks, but the split may result is a body made up of many chunks that all need to be split up.
The idea is that the macro would figure out which face to select on its own in order to separate the two (or more) parts.

Do you know how to approach this problem of telling which faces are part of which chunk?

A very naive way to do this would be to select face0 and do the split resulting in a geometry (call the resulting geometry split0).
Then we do another split using a randomly selected face and get resulting geometry (call the resulting geometry randomSplit).
We can check if the center of mass of split0 is the same as the center of mass of randomSplit.
If they are the same
then we did the same split that we did before and we need to try again.​
If they are not the same
then we have done a new split and have successfully separated the two chunks​
And we keep doing this until we have tested all of the faces.

This works, but is very naive and inefficient as the body will have many faces. It seems like there should be a better way of telling the two chunks apart.

Note: I changed the code a little bit so now it operates on any body that you select.

Code:
Sub CATMain()

Dim partDocument1 As PartDocument
Set partDocument1 = CATIA.ActiveDocument

Dim part1 As Part
Set part1 = partDocument1.Part

Dim bodies1 As Bodies
Set bodies1 = part1.Bodies

Dim USel As Selection

Set USel = CATIA.ActiveDocument.Selection
Set USelLB = USel

Dim body1 As Body
Set body1 = USel.Item(1).Value

MsgBox TypeName(USel.Item(1).Value)

USel.Clear

part1.InWorkObject = body1

Dim shapeFactory1 As ShapeFactory
Set shapeFactory1 = part1.ShapeFactory

Dim trim1 As Trim
Set trim1 = shapeFactory1.AddNewTrim(body1)

Dim shapes1 As Shapes
Set shapes1 = body1.Shapes

Dim EnabledObjectSelection1(0)
EnabledObjectSelection1(0) = "Face"
Dim osel2 As Object
Set osel2 = partDocument1.Selection
Dim status2 As String

MsgBox "Select the face to remove!"

status2 = osel2.SelectElement2(EnabledObjectSelection1, "Select face ", False)
If status2 = "Normal" And osel2.Count = 1 Then

Dim face1 As Face
Set face1 = osel2.Item(1).Value

End If

trim1.AddFaceToRemove face1

part1.Update

End Sub
 
do you need to know the history of the split? if not i.e. you are just interested in the lumps, I'd suggest moving over to GSD (surfaces). there you can use disassemble(domains) feature on your split...
and then for each disassembled (and dead) feature you just create a solid.

regards,
LWolf
 

Dim hybridShapeFactory1 As HybridShapeFactory
Set hybridShapeFactory1 = part1.HybridShapeFactory

Dim hybridShapeExtract1 As HybridShapeExtract
Set hybridShapeExtract1 = hybridShapeFactory1.AddNewExtract(reference1)
hybridShapeExtract1.Compute

Dim HShape
HShape = part1.HybridShapeFactory.AddNewDatums(hybridShapeExtract1)
If UBound(HShape) > 1 Then
'create bodies with solids based on HShape​
end if

regards,
LWolf
 
Hi LWolf (and Little Cthulhu and ferdo), this is a really good answer and I got it working. Thank you!

Unfortunately, this is part of a larger macro that I have already written a lot of which would require significant reworking.
Before put in the hours to switch it over to surfaces, I want to ask one more question.

I have an idea for how to solve this problem another way, but I just need to figure out how to get a face on the body with VBA without user input, can be any face.
Is there some list of faces that I can just access and do something like:

Dim face1 As Face
face1 = body1.faces(1)

is this possible?

Thanks so much for the help,
Sam

In case this is useful to anyone, here is the working example using LWolf's starting code

Code:
'' Extracts as surface and separates
'' SELECT THE BODY FIRST BEFORE RUNNING THE MACRO

Sub CATMain()

Dim partDocument1 As PartDocument
Set partDocument1 = CATIA.ActiveDocument

Dim part1 As Part
Set part1 = partDocument1.Part

Dim bodies1 As Bodies
Set bodies1 = part1.Bodies

Dim USel As Selection

Set USel = CATIA.ActiveDocument.Selection
Set USelLB = USel

Dim body1 As Body
Set body1 = USel.Item(1).Value

MsgBox TypeName(USel.Item(1).Value)

USel.Clear

part1.InWorkObject = body1

Dim hybridBody1 As HybridBody
Set hybridBody1 = part1.HybridBodies.Add()

hybridBody1.Name = "Extract features"

Dim reference1 As Reference
Set reference1 = part1.CreateReferenceFromObject(body1)

Dim hybridShapeFactory1 As HybridShapeFactory
Set hybridShapeFactory1 = part1.HybridShapeFactory

Dim hybridShapeExtract1 As HybridShapeExtract
Set hybridShapeExtract1 = hybridShapeFactory1.AddNewExtract(reference1)
hybridShapeExtract1.Compute

Dim HShape
HShape = part1.HybridShapeFactory.AddNewDatums(hybridShapeExtract1)

num = UBound(HShape)
For i = 0 To num
    hybridBody1.AppendHybridShape HShape(i)
Next
part1.InWorkObject = HShape(num)
part1.Update

End Sub
 
Sam said:
Dim face1 As Face
face1 = body1.faces(1)

It's possible with Selection.Search:

Code:
Dim sel: set sel = CATIA.ActiveDocument.Selection

sel.Clear
sel.Add body
sel.Search "Topology.CGMFace,sel"
dim faces: set faces = CreateObject("System.Collections.ArrayList")
dim i: for i=1 to sel.Count
  faces.Add sel.Item(i).Value
next

By the way, I believe you don't have to switch to GSD in order to leverage LWolf's idea.

You perform an extract, disassemble and then make two sets of faces: from body and from disassemble that can be mapped together using COG measurement you mentioned. Figure out what disassembled face you want to use, find it's match among original body faces and move on with it, leaving GSD aside.
 
Disassemble would require WIN API... (and we might have to go explain the process again)

But if you Extract a face with propagation, the result should be the lump solid extract. So keep looping face and extract and if cog of extract already exist , then discard.

This should result in as many Extract as lump solid.

good post... many good idea here.


Eric N.
indocti discant et ament meminisse periti
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top