my algorithm is almost identical to the Serejah's:
fn distanceToSegment p A B ¶m: &dist: =
(
v = B - A
param = dot v (p - A) / dot v v
proj = A + v * param
dist = distance p proj
if (param < 0) then distance p A else if (param > 1) then distance p B else dist
)
fn getPolyEdgeParamPoint poly edge param =
(
vv = polyop.getEdgeVerts poly edge
v1 = polyop.getVert poly vv[1]
v2 = polyop.getVert poly vv[2]
v1 * (1 - param) + v2 * param
)
fn dividePolyEdgeAt poly edge point =
(
vv = polyop.getEdgeVerts poly edge
v1 = polyop.getVert poly vv[1]
v2 = polyop.getVert poly vv[2]
param = distance v1 point / distance v1 v2
polyop.divideEdge poly edge param
)
fn multiDividePolyEdge poly edge params =
(
sort params
points = for param in params collect (getPolyEdgeParamPoint poly edge param)
new_verts = #()
nume = poly.edges.count
for point in points do
(
v = dividePolyEdgeAt poly edge point
if (v > 0) do
(
nume += 1
edge = nume
append new_verts v
)
)
new_verts
)
fn weldClosePolyEdges poly threshold:0.5 weld:on select:on =
(
if threshold != unsupplied then poly.weldThreshold = threshold else threshold = poly.weldThreshold
open_ee = polyop.getOpenEdges poly
open_vv = polyop.getVertsUsingEdge poly open_ee
ee_table = #()
weld_vv = #{}
getvertpos = polyop.getVert
getvertedges = polyop.getEdgesUsingVert
getedgeverts = polyop.getEdgeVerts
for v in open_vv do
(
pt = getvertpos poly v
ee = getvertedges poly v
found = off
for e in open_ee while not found where not ee[e] do
(
vv = getedgeverts poly e
v1 = getvertpos poly vv[1]
v2 = getvertpos poly vv[2]
distanceToSegment pt v1 v2 param:&p dist:&d
if (found = (p > 0 and p < 1 and d < threshold)) do
(
if ee_table[e] == undefined do ee_table[e] = #()
append ee_table[e] p
append weld_vv v
)
)
)
for e=1 to ee_table.count where (params = ee_table[e]) != undefined do
(
vv = multiDividePolyEdge poly e params
if vv.count > 0 do join weld_vv (tobits vv)
)
if select do poly.selectedverts = weld_vv
if weld do polyop.weldVertsByThreshold poly weld_vv
ok
)
a test scene:
delete objects
(
p0 = plane width:30 length:10 pos:[-4,0,10.1] dir:y_axis wirecolor:yellow
p1 = plane width:20 length:10 pos:[0,0,0] dir:y_axis wirecolor:orange
p2 = plane width:40 length:10 pos:[3.5,0,-10.1] dir:y_axis wirecolor:brown
converttopoly p0
polyop.attach p0 p1
polyop.attach p0 p2
polyop.deletefaces p0 #{17, 20, 30..31}
update p0
p0.vertexticks = on
select p0
)
the using:
weldClosePolyEdges $ threshold:0.2 weld:off select:on -- or use weld ON