Auto CurveBoolean question

So I have been trying to make a script to accomplish this task. I think pics would best show what I am trying to do.

Before CurveBoolean

Mid CurveBoolean

After CurveBoolean = End Result

Now I have been around the block with this. I’ve tried functions in Python, Rhinocommon(VB.NET), and Rhinoscript and I still can’t get this to work.

I even tried a hidden “test” command called TestGetPlanarRegions.

My plan with that was simple.

Get the long lines, store them
Get the inside border line (boundary), store it
Perform TestGetPlanarRegions on each object
Run BooleanDifference, store the result.
Duplicating those as curves
Then finally deleting the surfaces and only leaving me with the curves.

But it’s just not working.

If ANYONE has any idea on how to get this going, please please let me know. This would be a LIFE and TIME saver if I could get this going.

VB.NET, C#, Python… anything you got!

Hi Alan,

How about:

Sort longlines in the height order.

Get sets of 2 longlines that are far apart (1+2)(3+4)(5+6) etc…
Split border by longlines
Get border segments between longlines
Perform a curve boolean with these sets and the border segments inbetween.

Let me know if it’s unclear
-Willem

yea I get what you’re saying. But what I am trying to get out of this whole thing is… NOT clicking inside each “island” during CurveBoolean… I want to select the long lines, then select the border and POOF, its all good.

What’s you’re thoughts on that @Willem ?

So I’ve come up with this for a solution…

The only problem, is that it leaves behind any lines that were touching the border… but this is start :slight_smile:

	Dim stTeak, stBorder
    	Dim surTeak, surBorder
    	Dim boolResult
    	Dim surToCurve
    	
    	stTeak = Rhino.GetObjects("Select the teak lines", 4, True)
    	If IsArray(stTeak) Then
    		
    		stBorder = Rhino.GetObjects("Select the border", 4, False)
    		If IsArray(stBorder) Then
    			
    			Rhino.UnselectAllObjects()
    			Rhino.SelectObjects(stTeak)
    			surTeak = Rhino.AddPlanarSrf(stTeak)
    			Rhino.DeleteObjects(stTeak)
    			Rhino.UnselectAllObjects()
    			
    			Rhino.SelectObjects(stBorder)
    			surBorder = Rhino.AddPlanarSrf(stBorder)
    			Rhino.DeleteObjects(stBorder)
    			Rhino.UnselectAllObjects()
    			
    			boolResult = Rhino.BooleanDifference(surBorder, surTeak)
    			
    			Rhino.SelectObjects(boolResult)
    			Rhino.Command("_DupBorder")
    			Rhino.DeleteObjects(boolResult)
    			
    			
    		Else
    			Exit Sub
    		End If
    		
    	Else
    		Exit Sub
    	End If
    End Sub

I see you are right that here is no obvious way to have a curve boolean with open curves…

How about this:

Sort longlines in the height order.

Get sets of 2 longlines that are far apart (1+2)(3+4)(5+6) etc…
Split border by longlines
Get border segments between longlines:
if 2 borderline segments between the longlines:
connect end to start end to strat
if 1 borderline segment between the longlines:
close segment

-Willem

I am an idiot…

Rhino has Rhino.CurveBooleanIntersection already… So everything is all good lol.

1 Like

Alan how much back scratching would it take to get you to share the final script?

I am rolling over here :joy:… only someone in our industry could spot what that was lol.

Sure thing. When I get in tomorrow, I’ll share it with you.

It was a lot easier than I thought.

The teak planks need to be the width of the actual plank… not the width of inbetween them… if that makes any sense lol.

Call Main()
Sub Main()

	Dim stCrvA, stCrvB
	Dim result
	Dim obj, objB, objC, objD
	
	stCrvA = Rhino.GetObjects("Select Teak", 0, True)
	stCrvB = Rhino.GetObjects("Select Border", 0)
	
	Rhino.Print("Working teak lines....")
	For Each obj In stCrvA
		For Each objB In stCrvB
			Rhino.CurveBooleanIntersection obj, objB
		Next
	Next
	
	Rhino.Print("Cleaning up loose objects.....")
	For Each objC In stCrvB
		Rhino.DeleteOBject(objC)
	Next
	
	Rhino.DeleteObjects(stCrvA)
	Rhino.Print("COMPLETE!")

End Sub

Now…

It’s pretty slow with lots of objects.

Also… according to the docs, Rhino.CurveBooleanIntersection is supposed to return the object that was created. Hence why I have a varible named result.

I was going to have it setup like so

result = Rhino.CurveBooleanIntersection obj, objB
Rhino.ObjectLayer result "Layername"

But result is always null.

I wanted to put all the objects that it returned on a certain layer, but anything that it returned was null for some reason.

Maybe @clement can shed some light on why this is.

I tried to mess with arrays and add each result to an array… but old school arrays confuse the hell out of me lol.

@AlanGreyjoy,

for slight speedup, you might change this snippet:

Rhino.Print("Cleaning up loose objects.....")
For Each objC In stCrvB
	Rhino.DeleteOBject(objC)
Next

to this, non loop version:

Rhino.DeleteObjects stCrvB

And to put results on layer i guess you forgot some brackets and a comma in this snippet:

result = Rhino.CurveBooleanIntersection obj, objB
Rhino.ObjectLayer result "Layername"

the correction would be:

result = Rhino.CurveBooleanIntersection(obj, objB)
If Not IsNull(result) Then Rhino.ObjectLayer result, "Layername"

For more speedups, you might change the redraw behaviour using Rhino.EnableRedraw(False) at the start of your script and turn it on again with Rhino.EnableRedraw(True) when the script finished or when an error occured. Note that the latter is required in case of errors, otherwise you’ll have to hold ESC to get the redraw back… :wink:

c.

Oh man… I feel silly…

I totally forgot to put that in parentheses…

Thanks for the EnableRedraw function!!!

This is awesome. Many thanks Alan.