Notifications
Clear all

[Closed] Point and slice plane

Hi! I have simple scene with teapot, and Slice modifier applied. Slice cuts it into pieces, all deatched into objects. Now I want to check out, which pieces ended up on the left side (normal facing), and which on the right side.

I’ve tried creating a plane object in the same position, as slice plane. Then doing this:

for OBJ in _detachedTeapotPieces do
(
centerPivot OBJ
_pos = OBJ.pivot (getNormal planeObject.mesh 1)
)

But results are always greater then 0, something like
1.1121
5.55656
e.t.c

while I expected to get < 0 for rights side, and > 0 for left side.

Where did I went wrong?

5 Replies
1 Reply
(@gazybara)
Joined: 11 months ago

Posts: 0

Try this


delete objects
sp = sphere radius:50 dir:[.56,.45,.2]
ResetXForm sp ; obj = converttopoly sp
getFaceCenter = polyop.getSafeFaceCenter
mody = SliceModifier()
addmodifier obj mody
objTM = obj.objectTransform
modTM = getModContextTM obj mody
side = #above --or #below
spTM = (modTM*objTM)
obj = converttopoly obj
selFaces = case side of (
	#above: (for f = 1 to obj.numfaces where in coordsys spTM (getFaceCenter obj f ).z > 0 collect f)
	#below: (for f = 1 to obj.numfaces where in coordsys spTM (getFaceCenter obj f ).z < 0 collect f)
)
select obj
obj.selectedfaces = selFaces
max modify mode
subobjectLevel = 4

Thank you, that really helps. I see that you are using Z value to test, the reason I began using normal is because my slice_plane can be rotated. Though I will try and see if I can modify your code to take rotation into account, right not it so compact and well-working that I want somehow to finish it until the very end

I have rewritten it to include normal calculation, but no matter what I always get valueslike 18 33 e.t.c.

Mi idea was to test face center against plane normal for distance, so one side would give positive distance, other negative.

Was I wrong at some part?

clearListener()
function planeFromNormal p3PlanePos p3PlaneNorm =
(
if ((classOf p3PlanePos) == Point3) and ((classOf p3PlaneNorm) == Point3) then
(
local m3Temp = matrixFromNormal (normalize(p3PlaneNorm))

    -- points for visual test
  --  point size:3 position:(p3PlanePos) wireColor:red
  --  point size:3 position:(p3PlanePos + m3Temp.row1) wireColor:green
  --  point size:3 position:(p3PlanePos + m3Temp.row2) wireColor:green
  --  point size:3 position:(p3PlanePos + p3PlaneNorm) wireColor:blue

    return #(p3PlanePos, (p3PlanePos + m3Temp.row1), (p3PlanePos + m3Temp.row2))
)
else
(
    throw "Wrong input in function planeFromNormal()"
)

)

fn pointPlaneDist pA pB pC pD = (
local nABC=normalize (cross (pB-pA) (pC-pA))
length ((dot (pA-pD) nABC)*nABC)
)

delete objects
sp = sphere radius:50 dir:[.56,.45,.2]
ResetXForm sp ; obj = converttopoly sp
getFaceCenter = polyop.getSafeFaceCenter
mody = SliceModifier()
–mody.Slice_Type =1
addmodifier obj mody
mody.slice_plane.rotation = (quat 0 0.343477 0 0.939161)

getFaceCenter = polyop.getSafeFaceCenter
objTM = obj.objectTransform
modTM = getModContextTM obj mody
side = #above –or #below
spTM = (modTM*objTM)
obj = converttopoly obj

_angle = (quatToEuler mody.slice_plane.rotation)
_normal = cross mody.slice_plane.position [_angle.x,_angle.y,_angle.z]
_points = planeFromNormal mody.slice_plane.position _normal

selFaces = case side of (
#above: (for f = 1 to obj.numfaces where in coordsys spTM pointPlaneDist _points[1] _points[2] _points[3] (getFaceCenter obj f ) > 0 collect f)
#below: (for f = 1 to obj.numfaces where in coordsys spTM (getFaceCenter obj f ).z < 0 collect f)
)

select obj
obj.selectedfaces = selFaces
max modify mode
subobjectLevel = 4

Yai! I managed to make it work! Here is the solution:

clearListener()
function planeFromNormal p3PlanePos p3PlaneNorm =
(
if ((classOf p3PlanePos) == Point3) and ((classOf p3PlaneNorm) == Point3) then
(
local m3Temp = matrixFromNormal (normalize(p3PlaneNorm))

    return #(p3PlanePos, (p3PlanePos + m3Temp.row1), (p3PlanePos + m3Temp.row2))
)
else
(
    throw "Wrong input in function planeFromNormal()"
)

)

fn pointPlaneDist pA pB pC pD = (
local nABC=normalize (cross (pB-pA) (pC-pA))
length ((dot (pA-pD) nABC)*nABC)
)

delete objects
sp = sphere radius:50
ResetXForm sp ; obj = converttopoly sp
getFaceCenter = polyop.getSafeFaceCenter
mody = SliceModifier()
mody.Slice_Type =1
addmodifier obj mody
mody.slice_plane.rotation = (quat 0 0.343477 0 0.939161)

_pl = Plane length:125 width:125 lengthsegs:1 widthsegs:1
_pl.rotation = mody.slice_plane.rotation
_pl.position = mody.slice_plane.position * obj.transform
ConvertTo _pl Editable_Poly
_normal = polyop.getFaceNormal _pl 1

modTM = getModContextTM obj mody
converttopoly sp

getFaceCenter = polyop.getSafeFaceCenter
objTM = obj.objectTransform

side = #above –or #below
spTM = (modTM*objTM)
obj = converttopoly obj

selFaces = case side of (
#above: (for f = 1 to obj.numfaces where in coordsys spTM dot _normal (getFaceCenter obj f ) < 0 collect f)
#below: (for f = 1 to obj.numfaces where in coordsys spTM (getFaceCenter obj f ).z < 0 collect f)
)

selFaces2 = case side of (
#above: (for f = 1 to obj.numfaces where in coordsys spTM dot _normal (getFaceCenter obj f ) < 9999999 do print (dot _normal (getFaceCenter obj f )))

)

select obj
obj.selectedfaces = selFaces
max modify mode
subobjectLevel = 4

I just correct the code to be able easy to read.
Don’t use “case of” statement if you have one condition to check. Better use “if…do” or “if…then…else”.


 clearListener()
 fn planeFromNormal p3PlanePos p3PlaneNorm =
 (
 	if ((classOf p3PlanePos) == Point3) and ((classOf p3PlaneNorm) == Point3) then
 	(
 		local m3Temp = matrixFromNormal (normalize(p3PlaneNorm))
 		return #(p3PlanePos, (p3PlanePos + m3Temp.row1), (p3PlanePos + m3Temp.row2))
 	)
 	else (throw "Wrong input in function planeFromNormal()")
 )
 fn pointPlaneDist pA pB pC pD = 
 (
 	local nABC=normalize (cross (pB-pA) (pC-pA))
 	length ((dot (pA-pD) nABC)*nABC)
 )
 (
 	delete objects
 	local getFaceCenter = polyop.getSafeFaceCenter
 	local sp = sphere radius:50
 	local mody = SliceModifier Slice_Type:1
 	ResetXForm sp ; 
 	local obj = converttopoly sp
 	addmodifier obj mody
 	mody.slice_plane.rotation = (quat 0 0.343477 0 0.939161)
 
 	local _pl = Plane length:125 width:125 lengthsegs:1 widthsegs:1
 	_pl.rotation = mody.slice_plane.rotation
 	_pl.position = mody.slice_plane.position * obj.transform
 	_pl = converttopoly _pl
 	_normal = polyop.getFaceNormal _pl 1
 
 	modTM = getModContextTM obj mody
 	objTM = obj.objectTransform
 
 	side = #above --or #below
 	spTM = (modTM*objTM)
 	obj = converttopoly obj
 
 	selFaces = case side of 
 	(
 		#above: (for f = 1 to obj.numfaces where in coordsys spTM dot _normal (getFaceCenter obj f ) < 0 collect f)
 		#below: (for f = 1 to obj.numfaces where in coordsys spTM (getFaceCenter obj f ).z < 0 collect f)
 	)
 	selFaces2 = if side == #above (for f = 1 to obj.numfaces where in coordsys spTM dot _normal (getFaceCenter obj f) < 9999999 do print (dot _normal (getFaceCenter obj f)))
 	select obj
 	obj.selectedfaces = selFaces
 	max modify mode
 	subobjectLevel = 4 
 )