Find % tolerance from knotA knotB

Hi all :)

I am here again to ask a question where I can not find solution :D

I created a small script where I find and I select two vertices overlapping (I recognize that it is a bit spartan as it is written the code, but I could not do better; if you know how to improve it you're welcome!!):

Create a spline with any number of knot. Break more knot and run the script (for now, don't move the break knot :D)

rollout d "DD" width:233 height:260
(
Global se = selection[1]
 
GroupBox gr_spline "Spline knot"  pos:[2,2] width:228 height:104
GroupBox gr_find "Find" pos:[8,20] width:216 height:50
spinner sp_tol "% " pos:[72,40] width:144 height:16 fieldWidth:50 range:[-1e5,1e5,0] 
button bt_check "Find Double Knot" pos:[16,40] width:120 height:16
 
spinner sp_weld_val "" pos:[72,80] width:144 height:16 fieldWidth:50 range:[-1e5,1e5,0.1] type:#worldunits scale:0.01
button bt_weld "Weld knot" pos:[16,80] width:120 height:16
 
on bt_check pressed do
(
 
try (
--- start code
local arr_knot = #(); arr_knotPoint =#(); arr_Spline =#(); arr1 =#(); arr2 =#()
updateshape se
 
k = numKnots se
for i = 1 to k do append arr_knot i
 
spl = numSplines se
for i = 1 to spl do append arr_Spline i
 
for i = 1 to spl do 
	(
		temp = numKnots se i
			for o = 1 to temp do
			(
				pos_knot = getKnotPoint se i o
				append arr_knotPoint pos_knot
			) 
	)
 
for i in arr_knotPoint.count to 1 by -1 do
	(
		if findItem arr1 arr_knotPoint[i] == 0 then append arr1 arr_knotPoint[i]
		else append  arr2 arr_knotPoint[i]
	)
 
 
for i = 1 to spl  do 
	(
 
		temp = numKnots se i
		sel_arr = #()
		for o = 1 to temp do
			(
				pos_knot = getKnotPoint se i o
				if findItem arr2 pos_knot != 0 do append sel_arr o
 
			) 
				setKnotSelection se i sel_arr
	)
--- end code
) catch()
)
 
on bt_weld pressed do
(
	try(
	weldSpline se sp_weld_val.value
	updateshape se
	)catch()
	bt_check.pressed()
)
 
 
)
createdialog d 

Now, I've insert a spinner to find the % of tolerance between two knot for check and select it. I tried "distance" (distance knotA knotB) but without result... really do not understand how to act in loop...

Situation in the real world:
With Spinner I determine the % of distance between two knot (0.0 = same location)for check and select it

Any Idea??

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
pixamoon's picture

`

hi, try something like this.
If I understood tolerance % idea this should find and select knots on spline:

rollout d "DD" width:233 height:260
(
	local se = selection[1]
 
	GroupBox gr_spline "Spline knot"  pos:[2,2] width:228 height:104
	GroupBox gr_find "Find" pos:[8,20] width:216 height:50
	spinner sp_tol "% " pos:[72,40] width:144 height:16 fieldWidth:50 range:[-1e5,1e5,0] 
	button bt_check "Find Double Knot" pos:[16,40] width:120 height:16
 
	spinner sp_weld_val "" pos:[72,80] width:144 height:16 fieldWidth:50 range:[-1e5,1e5,0.1] type:#worldunits scale:0.01
	button bt_weld "Weld knot" pos:[16,80] width:120 height:16
 
	on bt_check pressed do (
		--- start code
		local allKnotPoints = #(), closeKnots = #()
		subobjectLevel = 0
 
		for s = 1 to numSplines se do 
			for k = 1 to numKnots se s do append allKnotPoints #(s, k, (getKnotPoint se s k))
 
		for i = 1 to allKnotPoints.count do
			for j = i + 1 to allKnotPoints.count where i != j do 
				if distance allKnotPoints[i][3] allKnotPoints[j][3] < (sp_weld_val.value * sp_tol.value /100) + sp_weld_val.value do (
					-- append knot information to array (spline index and knot index)
					appendifunique closeKnots #(allKnotPoints[i][1],allKnotPoints[i][2])
					appendifunique closeKnots #(allKnotPoints[j][1],allKnotPoints[j][2])
				)
 
		-- deselect all
		for s = 1 to numSplines se do setKnotSelection se s #() 
 
		-- select form array
		for a in closeKnots do setKnotSelection se a[1] #(a[2]) keep:true 
		updateshape se
		subobjectLevel = 1
 
	)--- end code
 
	on bt_weld pressed do (
		try(
		weldSpline se sp_weld_val.value
		updateshape se
		)catch()
		bt_check.pressed()
	)
)
createdialog d 

First it collect all points on all spines inside object.
Then collect if distance is smaller than (weldSpiner.value + % of weldSpiner.value)

Michele71's picture

Make your selection with the

Make your selection with the only value of the spinner is a good compromise, but not the greatest :D

if distance allKnotPoints[i][3] allKnotPoints[j][3] <= sp_tol.value do

Thanks again pixamoon for the tip and have adjusted the code :) I keep studying...

pixamoon's picture

`

oki, how about this one.
It finds max position of knots in shape first. Then select by 1-100% of max distance only single knots (first and last of each spline)

It has also Auto button, so it auto select every time you change spinner.

(
	try(destroyDialog ::d)catch()
 
	rollout d "DD" width:233 height:260
	(
		local se = selection[1]
 
		GroupBox gr_spline "Spline knot"  pos:[2,2] width:228 height:104
		GroupBox gr_find "Find" pos:[8,20] width:216 height:50
		spinner sp_tol "% " pos:[72,40] width:144 height:16 fieldWidth:50 range:[0,101,0] 
		button bt_check "Find Double Knot" pos:[16,40] width:104 height:16
		checkbutton bt_Auto "A" pos:[120,40] width:16 height:16 checked:true
 
		spinner sp_weld_val "" pos:[72,80] width:144 height:16 fieldWidth:50 range:[-1e5,1e5,0.1] type:#worldunits scale:0.01
		button bt_weld "Weld knot" pos:[16,80] width:120 height:16
 
		fn selectbytol = if se !=undefined do (		--- start code
			local allKnotPoints = #()
			local sKnotPoints = #() -- single knots only (first and last)
			local tolKnots = #()
 
			--subobjectLevel = 0
 
			for s = 1 to numSplines se do 
				for k = 1 to numKnots se s do append allKnotPoints #(s, k, (getKnotPoint se s k))
 
			maxDistance = 0
			for i = 1 to allKnotPoints.count do 
				for j = i + 1 to allKnotPoints.count where i != j and maxDistance < (d = distance allKnotPoints[i][3] allKnotPoints[j][3]) do maxDistance = d
 
			for s = 1 to numSplines se do (
				append sKnotPoints #(s, 1, (getKnotPoint se s 1))	-------------------------------- add first knot
				a = numKnots se s
				append sKnotPoints #(s, a, (getKnotPoint se s a))	-------------------------------- add last knot
			)
 
			for i = 1 to sKnotPoints.count do
				for j = i + 1 to sKnotPoints.count where i != j do 
					if distance sKnotPoints[i][3] sKnotPoints[j][3] < (maxDistance * sp_tol.value /100) do (
						-- append knot information to array (spline index and knot index)
						appendifunique tolKnots #(sKnotPoints[i][1],sKnotPoints[i][2])
						appendifunique tolKnots #(sKnotPoints[j][1],sKnotPoints[j][2])
					)
 
			-- deselect all
			for s = 1 to numSplines se do setKnotSelection se s #() 
 
			-- select form array
			for a in tolKnots do setKnotSelection se a[1] #(a[2]) keep:true 
			updateshape se
			subobjectLevel = 1
		)-- end code
 
 
		on bt_check pressed do selectbytol()
 
		on bt_Auto changed e do if e do selectbytol()
 
		on sp_tol changed e do if bt_Auto.state do selectbytol()
 
		on bt_weld pressed do (
			try(
			weldSpline se sp_weld_val.value
			updateshape se
			)catch()
			bt_check.pressed()
		)
	)
	createdialog d 
)
Michele71's picture

Nice! Yes, is what I was

Nice! Yes, is what I was looking for :) thank you very much pixamoon!!!

pixamoon's picture

`

no prob man, this is nice idea too.

Michele71's picture

Thanks pixamoon good

Thanks pixamoon good solution, but it should not work in junction with weld spinner. I check another.

The Spinner value sp_tol "% " must find a maximum length position between two knots. If sp_tol is minor or ugual the knot are selected (works similar to weld). In short, a tolerance for the selection of the vertices (now are selected two knot overlapping in the same position); Selection of knot overlapping and those closest possible. The single knot need not be selected!

I try with distance fn, but I don't understand how put it in a loop seeing serve two values.

Thanks for you help and patience! :)

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.