# 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 =#()

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
)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??

## Comment viewing options

### `

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
subobjectLevel = 1

)--- end code

on bt_weld pressed do (
try(
weldSpline se sp_weld_val.value
)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)

### 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...

### `

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
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
)catch()
bt_check.pressed()
)
)
createdialog d
)```

### Nice! Yes, is what I was

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

### `

no prob man, this is nice idea too.

### 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! :)