Notifications
Clear all

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

8 Replies

how is about this situation?

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.

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

rubbish. we need probably some grid based solution to work it fast.

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.

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

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.