PDA

View Full Version : Select Faces based on normal?


NeonMojo
06-21-2007, 07:44 PM
I am trying to select all the faces of a poly that have their normal pointing above the horizon, i.e. "upwards". Any ideas?? I am not that familar with matrix math and trying to wrap my head around it so any explainations would also be most helpful. Thanks.

Vsai
06-21-2007, 09:21 PM
gonna cut and paste a few things.. not quite a full ready to use script, but it does something similar to what you want ;)



group "Select Angled Faces: " (
spinner ui_MinDegree "Min: " pos:[8,135] width:118 height:16 range:[0,360,15]
spinner ui_MaxDegree "Max: " pos:[8,157] width:118 height:16 range:[0,360,90]
)



function SelectAngleFaces =
(
curObj = (getCurrentSelection())[1]
if curObj != undefined do
(
--if classof curObj == editable_patch then addmodifier curObj (Edit_mesh())

if (getSelectionLevel $ != #face) do
(
modPanel.setCurrentObject $.baseObject
subobjectLevel = 4
)

numFaces = polyOp.GetNumFaces curObj
angleSelection = #{}
minAngle = ui_MinDegree.value
maxAngle = ui_MaxDegree.value

for f=1 to (numFaces) do
(
faceNorm = polyOp.getFaceNormal curObj f
angle = (acos (dot faceNorm [0,0,1] ))
if ((angle >= minAngle) and (angle <= maxAngle)) then angleSelection[f] = true
)
polyOp.setFaceSelection curObj angleSelection
forceCompleteRedraw()
)
)


on ui_MinDegree changed val do (
ui_MinDegree.value = val

ui_MaxDegree.range = [val,360, ui_MaxDegree.value]

SelectAngleFaces()
)

on ui_MaxDegree changed val do (
ui_MaxDegree.value = val

ui_MinDegree.range = [0,val, ui_MinDegree.value]

SelectAngleFaces()
)




build yourself a rollout for it and you should be good ;)

NeonMojo
06-21-2007, 09:56 PM
i think i figured out a way but not sure if it is 100% correct... any comments?


-- check if object is an editable poly
if (classof obj == Editable_Poly) then
(
max modify mode
subObjectLevel = 4
sf = #()

-- loop through all the faces
for fIndex = 1 to obj.numfaces do
(

-- n1 is set to face normal
n1 = getFaceNormal obj fIndex

-- n2 is set to "up"
n2 = [0,0,1]

-- get the angle between the vectors
angleBetween = acos(dot n1 n2)

-- check if angle is less then 90 degress from "up"
if (angleBetween < 90) then
(
-- add face index to array
append sf fIndex
)
)
obj.selectedFaces = sf
)

NeonMojo
06-21-2007, 10:00 PM
thanks for the reply! i didn't see your post until after i posted my code. Seems like i am doing basically the same things. I like the min max angle spinners though. I will have to implement those.

magicm
06-21-2007, 10:19 PM
I might be terribly wrong here, but I think angle = acos faceNorm.z will return the same results as angle = (acos (dot faceNorm [0,0,1] )). So that eliminates the need for a dot product, which might speed up the script a tiny little bit on large datasets.

Cheers,
Martijn

NeonMojo
06-21-2007, 10:41 PM
Replacing the dot product line with angle = acos faceNorm.z does seems to work fine so far. Thanks for the suggestion.

Rivendale
06-22-2007, 04:46 PM
Hey, in the first example with the editable poly object...polyop.getFaceNormal will written like that return the local normal to the object. To get it in world coordinates you can add node:curObj to the end...like so: polyop.getFaceNormal curObj f node:curObj Editable meshes returns it in world coordinates by default though.

cheers,
CML

CGTalk Moderation
06-22-2007, 04:46 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.