Obtain sub-surfaces after BooleanDifference using RhinoCommon

So I have successfully generated two surfaces and trimmed both of them using BooleanDifference, but that operation automatically joins all breps into one, bigger brep:

Unfortunately I need to obtain the surfaces seperately and not joined together. Can this be done using RC or should I use something else instead of BooleanDifference to trim both surfaces? BooleanDifference essentially is nothing but a fancy combination of intersect, trim, join etc. commands right? So maybe it can be recreated without the join at the end if necessary?

It shouldn’t if the wing profile is closed and the surface normals of the larger surface are pointing “toward” the part of the wing that you want to keep.

Boolean operations rely on surface normals to determine which parts to keep and which to delete . In this case it looks like it’s getting confused. Try Dir to show the surface normals on both. Flip the normals if necessary and try again.

https://wiki.mcneel.com/rhino/booleanfaq

HTH, --Mitch

Hey Mitch, unfortunately it does. I have found an alternative though (at least I think):

Rhino.Geometry.Brep.Trim(wing,boundary,0.1)
Rhino.Geometry.Brep.Trim(boundary,wing,0.1)

This seems to trim both breps with each other at least. This is what I should have done to begin with perhaps. This obviously doesn’t really beat BooleanDifference if you still need to call

Rhino.Geometry.Brep.JoinBreps([brepslist],0.1)[0] amongst other commands

But for my purposes it does the trick, because it neatly keeps everything separated until I actually want to join breps. I’ll have alook at the the BooleanDifference command later though to see exactly how it works and what should/shouldn’t happen.

Your link should help me out in the future.

OK, if you can post the surfaces before the BooleanDifference (or PM), it would be interesting to understand why it’s not working as expected…

Example.3dm (485.3 KB)

Dunno, I get this after BD’ing the big surface from the wing profile here… (native Rhino command)

that doesn’t happen on your end?

I also get the same result with a quickie script:

import rhinoscriptsyntax as rs
base_obj=rs.GetObject()
sub_obj=rs.GetObject()
rs.BooleanDifference(base_obj,sub_obj)

Maybe you can help me with something else as well:

extrusions = [Rhino.Geometry.Brep.JoinBreps(x,0.1)[0] for x in zip(extrusionsLow,extrusionsHigh)]
bounds = [lowBoundary, highBoundary]
extrusions = [Rhino.Geometry.Brep.Trim(x,y,0.1)[0] for x in extrusions for y in bounds]

The last line creates two breps, one cut left and one cut right. Would it be possible to reuse the result of the first y-loop instead of reusing the initial geometry? :slight_smile:

PS The first line is a bit odd because I need to treat my trailing edge surfaces differently.

Hard to really know what’s going on without knowing what variables like ‘x’ really contain, and without having some geometry…

Yes of course,

x is a list containg:

The trailing edge, and:

The rest of the wing. I’ll create an example file.

Wew, that took way too long. Here it is:

import Rhino
from math import pi

bound1 = 10
bound2 = 20

origin = Rhino.Geometry.Point3d(0,0,0)
lower = Rhino.Geometry.Point3d(0,0,bound1)
upper = Rhino.Geometry.Point3d(0,0,bound2)
vectorZ = Rhino.Geometry.Vector3d(0,0,1)
vectorY = Rhino.Geometry.Vector3d(0,1,0)
planeZ = Rhino.Geometry.Plane(origin,vectorZ)
planeY = Rhino.Geometry.Plane(origin,vectorY)
radius = 5
height = 30

arcs = [Rhino.Geometry.Arc(planeZ, radius, x) for x in [pi,-pi]]
curves = [x.ToNurbsCurve() for x in arcs]
extrusions = [Rhino.Geometry.Extrusion.CreateExtrusion(x,height*vectorZ) for x in curves]
breps = [x.ToBrep() for x in extrusions]

lowerBound = Rhino.Geometry.Plane(lower,vectorZ)
upperBound = Rhino.Geometry.Plane(upper,vectorZ)

bounds = [lowerBound,upperBound]

trims = [Rhino.Geometry.Brep.Trim(x,y,0.1)[0] for x in breps for y in bounds]

[Rhino.RhinoDoc.ActiveDoc.Objects.AddBrep(x) for x in trims]

OK, I see it creates 4 half-cylinder surfaces, one 10 and one 20 in height… which looks OK at first glance as you are trimming two half-cylinder extrusions of height=30 with a plane at Z=10 and another plane at Z=20…

What are you expecting to see?

Shoot. Forgot to flip surface normals on lower bounds:

Example.py (942 Bytes)

What I get (expand figures to see properly):

What I’m trying to achieve:

I left the right half intact as a reference, but it should also happen for the right side. So basically: Carry the first trim to the second trim, instead of trimming the untrimmed surface twice.

How about:

import Rhino
import scriptcontext as sc
from math import pi

bound1 = 10
bound2 = 20

origin = Rhino.Geometry.Point3d(0,0,0)
lower = Rhino.Geometry.Point3d(0,0,bound1)
upper = Rhino.Geometry.Point3d(0,0,bound2)
vectorZ = Rhino.Geometry.Vector3d(0,0,1)
vectorY = Rhino.Geometry.Vector3d(0,1,0)
planeZ = Rhino.Geometry.Plane(origin,vectorZ)
planeY = Rhino.Geometry.Plane(origin,vectorY)
radius = 5
height = 30

arcs = [Rhino.Geometry.Arc(planeZ, radius, x) for x in [pi,-pi]]
curves = [x.ToNurbsCurve() for x in arcs]
extrusions = [Rhino.Geometry.Extrusion.CreateExtrusion(x,height*vectorZ) for x in curves]
breps = [x.ToBrep() for x in extrusions]

lowerBound = Rhino.Geometry.Plane(lower,-vectorZ)
#lowerBound.Flip()
upperBound = Rhino.Geometry.Plane(upper,vectorZ)

bounds = [lowerBound,upperBound]

trimmed=[]
for x in breps:
    for y in bounds:
        result=Rhino.Geometry.Brep.Trim(x,y,0.1)
        #feed the trimmed result back into the loop to be trimmed again
        x=result[0]
    #done with x, add to trimmed list, move to next x in breps
    trimmed.append(x)
[sc.doc.Objects.AddBrep(x) for x in trimmed]
sc.doc.Views.Redraw()

Yes that works! I was hoping to do it with a list comprehension but to be honest I think I’m asking too much. Thanks for all the help as always!

Any further info on that pesky BooleanDifference?

List comprehensions are cool, but sometimes they also make your code less readable/understandable. When things don’t work as you think they should, first type out your loop explicitly and set breakpoints to see why.

Like I said further up, it works here…??

I somehow missed this post. No, I did not get this. I get the wing and the inner surface joined together.

Wow, you must be in a parallel universe from mine… :stuck_out_tongue_winking_eye:

All I did is download your file, call BD, click on the wing profile, Enter, click on the large surface, Enter and the result was like the image I posted in post #6

No I think I know what’s going on :smiley:. This is mostly due to my lack of understanding of the boolean functions I think. I’ll read up on the functions and if all else fails I’ll be fine with the normal functions anyway :slight_smile:

Thanks Mitch!

One of my go-to commands is using BooleanSplit instead of BooleanDifference. It leaves all the parts and you can delete what you don’t want after.

There is also Boolean2Objects (if you have only two) which lets you cycle through all the possible result combinations and pick which one you want.

I’ll give it a go!