Best way to cut half slots for a lattice of 15mm mdf?

You’re right, of course - it’s just that this one already existed in RS, I found it under the wood pile by the shed, so I just cleaned it up and made it work in more cases… but, a week or two of conversion time would be nice for a pile of these that I have laying around. I’ll see if I can make this one work in Python… there are many more possibilites of course, so it can probably be made to work better.

-Pascal

1 Like

heh… yeah, sorry about always being pesky (pesty?) about this mac stuff… I figure if I keep at it, cross platform compatibility with rhino will be standard mindset for most coders in 5 years from now.

it doesn’t really matter though… if rhino for mac stayed exactly how it is right now, I’d still use it as my main drawing tool. :wink:

Hi Pascal
Your Notcher script looks ideal for a job I have - however, when I run it in Rhino 5, I get an error on line 85:
Variable is undefined: 'VecDir’
Do you have an updated version of the script or could you suggest something that could replace it?
The job is to create the templates for forming curved surfaces to - generating the required surfaces and solids isn’t particularly time consuming and being able to add the slots with an offset in Rhino saves a job I currently do in Solidworks.
Any suggestions gratefully received.
Thanks
Deri

Hi Deri, I’ll take a look - hang on a bit.

Notcher.rvb (5.7 KB)

@Deri_Jones - try the one attached here - I think the one above was a mistake…

Any better?

-Pascal

Like a champion! That has saved me a good bit of time, very much appreciated…

WOW, this is an awesome script!! Im trying to turn it into a button for easy access. And Im in way over my head. LOL

I tried: https://wiki.mcneel.com/_detail/legacy/en/edittoolbarbutton2.gif?id=rhino%3Amacroscriptsetup

But what part must of the script must I paste in? Pascal or anyone. :blush: Im really a complete armature.

Also Pascal cant you please write this into a tool for grasshopper?

Script :

Option Explicit
’Script written by Pascal
’ RMA
’Script version Wednesday, May 01, 2013

Rhino.AddStartUpScript Rhino.LastLoadedScriptFile
Rhino.AddAlias “Notcher”, “_NoEcho _-Runscript (Notcher)”

'Cuts two intersecting panels with notches for assembly. No clearance.
'Call Notcher()
Private OldClear

If isEmpty(oldClear) Then
oldClear = 0

End If

Sub Notcher()

Dim P1, P2
Dim aP, aUsed(), n
n = 0

P1 = Rhino.GetObject("Select the first panel.", 16, True, True) 
If isNull(P1) Then Exit Sub

Dim dblClear: dblClear = Rhino.GetReal("Add clearance? Enter 0 for none.", oldClear)
If isNull(dblClear) Then Exit Sub
OldClear = dblClear


Do
	Do
		P2 = Rhino.GetObject("Select an intersecting panel to notch. Press Enter when done.", 16, False, True) 
		If isNull(P2) Then Exit Sub
	Loop Until P1 <> P2 And Not IsStringInArray(P2, aUsed, 0)
	
	Rhino.SelectObject P1
	Rhino.EnableRedraw False
	aP = MakeNotch(array(P1, P2), dblClear)
	P1 = aP(1)
	ReDim Preserve aUsed(n)
	aUsed(n) = aP(0)
	n = n + 1
	Rhino.EnableRedraw True	
	
Loop Until IsNull(P2)

End Sub

Function MakeNotch(aPanels, dblClear)

Rhino.EnableRedraw False

Dim aInt: aInt = Rhino.IntersectBreps(aPanels(0), aPanels(1))

If Not isArray(aInt) Then
	Rhino.EnableRedraw True
	Exit Function
End If

Dim aExp: aExp = Rhino.ExplodeCurves(aInt, True, True)


Dim aLongest: aLongest = SortCurvesByLength(aExp)

If isArray(aLongest) Then
	Dim Bound: Bound = UBound(aLongest)
	If Bound < 7 Then Exit Function
	Else
		Exit Function
End If

Dim longest: longest = aLongest(bound)

Dim MidPlane: MidPlane = rhino.PlanefromNormal(Rhino.CurveMidPoint(longest), Rhino.VectorCreate(Rhino.CurveStartPoint(longest), Rhino.CurveEndPoint(longest)))

'	drawPLaneFrame aPlane, 10

Dim aBB: aBB = Rhino.BoundingBox(AExp, MidPlane)
'	Dim midPlane: midPlane = Rhino.RotatePlane(aPlane, 90, aPlane(2))

Dim aBaseCrv 
ReDim aBaseCrv(Ubound(aLongest)-4)

Dim i
Dim Xform: Xform = Rhino.XformPlanarProjection(MidPLane)
For i = 0 To Ubound(aLongest) - 4
	aBaseCrv(i) = Rhino.TransformObject(aLongest(i), Xform)
Next

Dim sBaseCrv: sBaseCrv = Rhino.JoinCurves(aBaseCrv, True)(0)

Rhino.SimplifyCurve sbaseCrv

If dblClear <> 0 Then
	Dim aOffset: aOffset = Rhino.OffsetCurve(sbaseCrv, Rhino.PointAdd(MidPlane(0), Rhino.VectorScale(MidPlane(1), Rhino.Distance(aBB(0), aBB(6)))), dblClear, MidPlane(3))
End If

Rhino.DeleteObject sbaseCrv
sbaseCrv = aOffset(0)

Dim CutterBase:CutterBase = Rhino.AddPlanarSrf(sBaseCrv)(0)

'Dim Dist: Dist = Rhino.Distance(aBB(0), aBB(6))
'	Dim aBase: aBase = Rhino.CurveMidPoint(longest)
'aPlane(0) = abase
Dim vec1, vec2
'drawPLaneFrame aPlane, 10
midPlane(0) = Rhino.CurveMidPoint(longest)

Vec1 = Rhino.VectorScale(Rhino.VectorCreate(Rhino.CurveEndPoint(longest), MidPlane(0)), 1.25)
vec2 = Rhino.VectorReverse(Vec1)

path1 = Rhino.AddLine(MidPlane(0), Rhino.PointAdd(MidPlane(0), vec2))
path2 = Rhino.AddLine(MidPlane(0), Rhino.PointAdd(MidPlane(0), vec1))
	
midPlane(0) = AveragePoints(aBB)
Dim testPanel, cutter0, cutter1, Path1, path2

'	Rhino.AddPoint Rhino.PointAdd(MidPlane(0), Vec1)

If Rhino.IsPointInSurface(aPanels(0), Rhino.PointAdd(MidPlane(0), Vec1)) Then

	Cutter1 = Rhino.ExtrudeSurface(CutterBase, path2)
	Cutter0 = Rhino.ExtrudeSurface(CutterBase, path1)
Else
	
	Cutter0 = Rhino.ExtrudeSurface(CutterBase, path2)
	Cutter1 = Rhino.ExtrudeSurface(CutterBase, path1)
End If
	
Rhino.DeleteObjects array(Cutterbase, sbaseCrv) 

Dim X, Y
X = Rhino.BooleanDifference(aPanels(1), cutter1, True)(0)
Y = Rhino.BooleanDifference(aPanels(0), cutter0, True)(0)

Rhino.DeleteObjects array(path1, path2)

Rhino.DeleteObjects(aExp)
MakeNotch = array(X, Y)

End Function

Function SortCurvesByLength(aCrvs)

Dim aLen, Bound
Bound = UBound(aCrvs)

ReDim aLen(Ubound(aCrvs))

Dim n
For n = 0 To Bound  
	aLen(n) = Rhino.CurveLength(aCrvs(n))
Next

Dim aSort: aSort = rhino.SortNumbers(aLen)
Dim result, i, j
i = 0
j = 0
ReDim result(Bound)

For i = 0 To Bound
	For j = 0 To bound
		If aLen(i) = aSort(j) Then 
			result(j) = aCrvs(i)
			aSort(j) = 0
			Exit For
		End If
	Next
Next

SortCurvesByLength = result

End Function

Public Function GetArrayDim(ByVal arr)
Dim i
If IsArray(arr) Then
For i = 1 To 60
On Error Resume Next
Call UBound(arr, i)
If Err.Number <> 0 Then
GetArrayDim = i - 1
Exit Function
End If
Next
GetArrayDim = i
Else
GetArrayDim = Null
End If

End Function

Function IsStringInArray(item, arr, intCase)
'Non case-sensitive= 0, case-sensitive = 1
IsStringInArray = False
If GetArrayDim(arr) = -1 Or IsEmpty(arr) Then

	Exit Function
	
End If

Dim sItem
	
If intCase = 0 Then
	For Each sItem In arr
		If LCase(sItem) = LCase(Item) Then
			IsStringInArray = True
			Exit For
		End If
	Next
Else
	For Each sItem In arr
		If sItem = Item Then
			IsStringInArray = True
			Exit For
		End If
	Next	
End If

End Function

Function AveragePoints(aPts)
'Finds the average coordinates of an array
’of points.

Dim X, Y, Z
Dim i

X = 0
Y = 0
Z = 0

For i=0 To UBound(aPts)
		
	'add all the X values
	X = X + aPts(i)(0)

	'add all th Y values
	Y = Y + aPts(i)(1)			

	'add all the Z values
	Z = Z + apts(i)(2)
Next

'Divide by the number of points to
'get the average  for each
'create the output array from the 3 averages
AveragePoints = array(X / (UBound(aPts) + 1), Y / (UBound(aPts) + 1), Z / (UBound(aPts) + 1))

End Function

Hi Sean - if you have drag-and-dropped the rvb file onto Rhino, then you just need to type in

Notcher

at the command line and the script will run. You can put that on a button as well.

Does that work?

-Pascal

Hi Pascal. I loaded it straight away. And have been using it. I want to make a button for it to add to my toolbar, that way I won’t forget about it and also Ill use it much more.

Only thing is I don’t really know how to make a button from a script.

Ive made my own toolbars but not a button before. I’ve drawn out a little bitmap and all for the notch button. . . but when I add the “full script” in the edit toolbar button, well I dont know what part of the script to copy and paste in there.

According to https://wiki.mcneel.com/_detail/legacy/en/edittoolbarbutton2.gif?id=rhino%3Amacroscriptsetup

Must I copy and paste everything or cutout bits like :

** Option Explicit**
’Script written by Pascal
’ RMA
’Script version Wednesday, May 01, 2013

I dont even know if its a python script or not. Would be cool to have a button. . Thanks for your script!

Hi Sean - that’s what I’m getting at - the script runs from an alias Notcher so you just need to put that on your button - it acts very much like a real command.

-Pascal

Got it! Works. I’ve made my first button.
Thank you.

Hi Pascal

If you ever update the notcher to Rhino 6 please let us know! Thank you.

Hi Sean - do you find it does not work in 6? I’ll have a look.

-Pascal

Hi Pascal

I get the following error. But it might just be me.
03%20(2)
03%20(2)|298x180

Hi Sean - that generally means it is not loaded - try drag and drop once more, the rvb file onto an open Rhino 6 window…

-Pascal

:roll_eyes: Sorry Pascal my bad! It works fine now.
. :clap: thank you !!

hey pascal,
i’m getting an error.
image

Hello - it looks like I never finished the job for zero clearance - try this one…

Notcher.rvb (5.8 KB)

-Pascal

1 Like

Hi Pascal,

Old thread but this notcher seems really straightforward to use but would it be positive to add a function to include the dogbones where the two notches meet? I started using your Bones.rhp last week but that seems to only work on closed curves projected to the World Plane but I like how the panel notching works in this script. Clearance for fit is very simple and if the next prompt could be for the dogbones would be great!

I’ll see if I can combine the functionality…but you’ll probably heve to pester me repeatedly, I am not sure when I’ll get to it.

-Pascal

But it has been three years already!!! Just kidding Pascal, thanks for your response.

Another approach might be that if one could do an ‘inverted fillet’ at the bottoms of the notches at the diameter of the cutter. Sort of like this-

I did this by using the pipe command of the edges of the bottom of the squared notch but I do remember people talking about a ‘invert fillet’ in the past. Maybe could be called a ‘dillet’?