ScriptSpot

Forum topic · General Scripting

Conform Script - Point Projection on Surface seems to work strange

By EliderDeli · 2018-05-28

Description

Hi Guys, I allready got a great support from the Forum!!! Im working on a Conform Script right know which I plan to use as a modifier. The Problem at the moment ist that the Plane Projection creates strange placing of my vertices. Basicly I search for the three enarest Vertices fro every vertice in my Object. Then I make a Point Projection on theSurface.

fn checkNearestEdge SelectedVerticeID =
(
oV = SelectedVerticeID.pos
pairs = for o in refObj.selectedVerts collect #(length(o.pos-oV), o.index ) --pairs distance and vertexpos
qsort pairs sortByDist --indexes and sorts

x0 = polyop.getVert refObj pairs[1][2]
x1 = polyop.getVert refObj pairs[2][2]
x2 = polyop.getVert refObj pairs[3][2]

offset = 0.01

x0 = x0 + [0,0,offset]
x1 = x1 + [0,0,offset]
x2 = x2 + [0,0,offset]

print "go"
print SelectedVerticeID.pos
print x0
print x1
print x2
newVert = pointPlaneProj x2 x1 x0 SelectedVerticeID.pos
moveVertices SelectedVerticeID.index newVert
)

-------------------------

fn pointPlaneProj pA pB pC pD = (
local nABC=normalize (cross (pB-pA) (pC-pA))
newPoint = pD+((dot (pA-pD) nABC)*nABC)
return newPoint
)

Comments (11)

EliderDeli · 2018-05-29

Okay wow tested it and no matter if my works its so much slower.... thanks a lot

EliderDeli · 2018-05-29

Thanks you very much. But i was trying to do it with the manuel Projection do u have any idears to that? Greetings

.

jahman · 2018-05-29

I don't quite understand what end result you're trying to achieve, sorry.


(
	delete objects
	delete helpers

	r = 20
	g = GeoSphere radius:r segments:2
	convertToMesh g

	points = for i=1 to 10 collect (
		
		pt = (normalize (random -[1.0,1.0,1.0] [1.0,1.0,1.0])) * r * 1.5
		point pos:pt centermarker:on cross:off wirecolor:yellow
		pt
		
	)

	mpi = MeshProjIntersect()
	mpi.setNode g
	mpi.build()

	for pt in points do (

		hit = mpi.ClosestFace pt
		
		if hit do (
			
			point pos:(mpi.GetHitPos()) centermarker:on cross:off wirecolor:red
			
		)
		
	)
)

EliderDeli · 2018-05-29

No Problem :D is my fault. Im making a Point on Surface projection with every Vertice to the three nearest Vertices of an Reference Mesh. So In theory if u have the Three Vertices u can create a Face and Project the Vertice on the shortest path onto this Face. So every Vertice should snap to the nearest point of a reference Mesh.
Greeting Eli

.

jahman · 2018-05-29

So isn't my example above (using MPI) doing exactly what you need? It creates red point helpers at the closest point on mesh.
Or maybe you need to place projected verts onto closest vert (not point on face)?

EliderDeli · 2018-05-29

No it does exactly what I need (Thanks a lot for that). Im only unsure why my code doesnt work and would be realyy interested where i made a mistake (it works but not for all vertices but iterate through all and checked at multiple parts in the script if the values are right).

fn checkNearestEdge SelectedVerticeID =
(
oV = SelectedVerticeID.pos
pairs = for o in refObj.selectedVerts collect #(length(o.pos-oV), o.index ) --pairs distance and vertexpos
qsort pairs sortByDist --indexes and sorts

x0 = polyop.getVert refObj pairs[1][2]
x1 = polyop.getVert refObj pairs[2][2]
x2 = polyop.getVert refObj pairs[3][2]

xoffset = 0.00
yoffset = 0.00
zoffset = 0.00

x0 = x0 + [xoffset,yoffset ,zoffset]
x1 = x1 + [xoffset,yoffset ,zoffset]
x2 = x2 + [xoffset,yoffset ,zoffset]

moveVertices SelectedVerticeID.index (pointPlaneProj x2 x1 x0 SelectedVerticeID.pos)
)

fn pointPlaneProj pA pB pC pD =
(
local nABC=normalize (cross (pB-pA) (pC-pA))
newPoint = pD+((dot (pA-pD) nABC)*nABC)
return newPoint
)

move just moves and works

Code Review

LAOMUSIC ARTS · 2025-08-03

Hi!

After checking your code, I noticed that;
- uninitialized variable — refObj is used but never defined or passed in.
- use of qsort without defining the sort function — qsort needs a comparison function.
- calling SelectedVerticeID.index — This depends on SelectedVerticeID being a valid subobject or having an .index, which might not be safe.
- potential misuse of selectedVerts — Ensure you are in subobject level 1 (vertex mode) and refObj is an editable poly.

Here is my suggestion:

fn pointPlaneProj pA pB pC pD =
(
local nABC = normalize (cross (pB - pA) (pC - pA))
return pD + ((dot (pA - pD) nABC) * nABC)
)

fn checkNearestEdge refObj vertIndex =
(
local oV = polyop.getVert refObj vertIndex

-- collect distances to all other selected verts
local pairs = for i in polyop.getVertSelection refObj where i != vertIndex collect
(
local otherV = polyop.getVert refObj i
#(distance oV otherV, i)
)

-- sort pairs by distance
qsort pairs (fn a b = a[1] < b[1])

if pairs.count < 2 then
(
format "Not enough nearby vertices found.\n"
return
)

local x0 = polyop.getVert refObj pairs[1][2]
local x1 = polyop.getVert refObj pairs[2][2]
local x2 = oV -- project this one

-- optional offset
local offset = [0,0,0]
x0 += offset
x1 += offset
x2 += offset

local projected = pointPlaneProj x0 x1 x2 oV
polyop.setVert refObj vertIndex projected
)

Usage example:
Make sure you’re in vertex subobject level and one vertex is selected
obj = $YourObjectName
selected = polyop.getVertSelection obj
if selected.numberset == 1 do checkNearestEdge obj selected as array

EliderDeli · 2018-06-04

Hi jahman thanks for your help till know. Maybe you hava an IDear hwo I could Confm my Mesh without converting it to editable_poly? I would like to build a script which conforms Vertices created thorugh a subdivison Modifer (Withouth collapsing it). Greetings EliderDeli

.

jahman · 2018-06-04

I guess simpleMod is your only option.
Google "simpleMod saddle" example

EliderDeli · 2018-06-05

Thank you very much ,again :). I will have a look at it