[Closed] How to find the verts that overlaps faces of the same mesh?
The verts in the red circles are in the wrong places. The object is flat(2D), so the verts and the faces lays on the same plane and have the same Z coordinates. Any ideas how to find those verts?
This also is possible situation. The verts can be over a face that is not a neighbor of this face. I want to start from somewhere. I was thinking to use intersectRay or RayMeshGridIntersect and to fire a ray from the vert(lifted up position) to the mesh, but sometimes the result is a face under the vert, sometimes the resuot is the face that belongs to the vert. This means that I hve to compare each vert with all faces, which will kill the speed of the script, but most important is to find a solution for small objects, then I can try to create something not so slower for objects with more dense geometry.
that’s why i’ve showed the case. you have to check not face or vert overlapping but the edge crossing.
This is what i’ve got so far. For an object with 650 edges and 200 cross points the time to find the cross edges is 11 – 13 sec.
How to speed up the script?
(
global rol_SelectCrossEdges
try(destroyDialog rol_SelectCrossEdges)catch()
rollout rol_SelectCrossEdges "Select cross edges"
(
local poGetEdgeVerts = polyop.getEdgeVerts
local poGetVert = polyop.getVert
button btn_getOverlappedVerts "Select cross edges"
function RoundFloat val dp =
(
res = [0,0,0]
for i = 1 to 3 do
(
a1 = (val[i] * (10^dp))
b = a1 as integer
res[i] = b as float / (10^dp)
)
--
res
)
function PointOfLinesIntersect pA pB pC pD =
(
local a = pB - pA
local b = pD - pC
local c = pC - pA
local cross1 = cross a b
local cross2 = cross c b
pA + ( a*( (dot cross2 cross1)/((length cross1)^2) ) )
)
fn IsPointOnLine pA pB pC pD crossPoint =
(
dist1 = distance pA pB
dist2 = distance pC pD
dist11 = distance pA crossPoint
dist12 = distance pB crossPoint
dist21 = distance pC crossPoint
dist22 = distance pD crossPoint
if dist1 > dist11 and dist1 > dist12 and dist2 > dist21 and dist2 > dist22 then
true else false
)
on btn_getOverlappedVerts pressed do
(
if selection.count == 1 and classof ( curO = (selection[1]) ) == Editable_Poly then
(
local allEdges = polyop.getNumEdges curO
local crossEdgesArr = #()
local edgesDataArr = #()
t0 = timestamp()
-- collect all edges and verts positions to avoid getting them for each edge multiple times
for i = 1 to allEdges do
(
iVerts = poGetEdgeVerts curO i
append edgesDataArr #(i, poGetVert curO iVerts[1], poGetVert curO iVerts[2])
)
for i = 1 to (edgesDataArr.count - 1) do
(
for j = (i + 1) to edgesDataArr.count do
(
pA = edgesDataArr[i][2]
pB = edgesDataArr[i][3]
pC = edgesDataArr[j][2]
pD = edgesDataArr[j][3]
crossPoint = PointOfLinesIntersect pA pB pC pD
-- round the float
pA = RoundFloat pA 3
pB = RoundFloat pB 3
pC = RoundFloat pC 3
pD = RoundFloat pD 3
crossPoint = RoundFloat crossPoint 3
-- check if the cross point match one of the edge's verts
if crossPoint != pA and crossPoint != pB and crossPoint != pC and crossPoint != pD do
(
if (IsPointOnLine pA pB pC pD crossPoint ) do
(
append crossEdgesArr #(edgesDataArr[i][1], edgesDataArr[j][1])
)
)
)
)
t1 = timestamp()
format "Time: %
" ((t1 - t0)/1000.0)
format "Cross edges count: %
" crossEdgesArr.count
)
else
messagebox "Select only one Editable Poly object" title:"Invalid Selection"
)
)
createdialog rol_SelectCrossEdges
)
I round up the floats to the 3 sign to avoid errors when compare crossPoint variable against the other points.
are you agree that we have to search an edge crossing instead of a vert over face?
An edge crossing works as I want. A vert over face will not work in some cases. So I agree that an edge crossing edge is the right path to solve the problem.
But if there is an edge that boes from botom left to top right, then it will cross more than one grid cell.
it doesn’t matter how many cells an edge crosses. algorithmically you have to check every edge againt all others. but with a grid you can narrow the search area.