Enrico Gullotti
earnest wonderer
earnest wonderer
Get Editable Poly / Mesh front faces
Get Front Faces <BitArray faceList> getFrontFaces <Editable_Poly | Editable_Mesh node> [step:<Integer default:0>] Returns a list of faces not occluded, with normal facing camera direction. Optional "step" parameter determines the creation of further points to test, causing a more accurate result if topology is made of both big and small faces. Calculation time is roughly multiplied by this value. Try 0 at first and increment by one step at a time if needed. Results can be fine tuned by adjusting the three float threshold at the beginning of the function, but current values should work well.
Required functions: getPolyFromMeshFace() found under: "Editable Poly data from underlying Mesh"
Get Front Faces <BitArray faceList> getFrontFacesByCenters <Editable_Poly | Editable_Mesh node> Returns a list of faces whose center point is not occluded, with normal facing camera direction. For Editable Polys, a face is considered not occluded only if the centers of all triangles constituting it are not occluded.
Required functions: getPolyFromMeshFace() found under: "Editable Poly data from underlying Mesh"
Get Front Faces <BitArray faceList> getFrontFaces <Editable_Poly | Editable_Mesh node> [step:<Integer default:0>] Returns a list of faces not occluded, with normal facing camera direction. Optional "step" parameter determines the creation of further points to test, causing a more accurate result if topology is made of both big and small faces. Calculation time is roughly multiplied by this value. Try 0 at first and increment by one step at a time if needed. Results can be fine tuned by adjusting the three float threshold at the beginning of the function, but current values should work well.
Required functions: getPolyFromMeshFace() found under: "Editable Poly data from underlying Mesh"
function posMatch pA pB fT = ( if ((classOf pA == Point3) and (classOf pB == Point3) and (classOf fT == Float)) then ( return (((abs(pA.x - pB.x)) < fT) and ((abs(pA.y - pB.y)) < fT) and ((abs(pA.z - pB.z)) < fT)) ) else ( throw "Wrong input in function posMatch()" ) ) -------------------------------------------------------------------------------- function getFrontFaces obj steps:0 = ( if ((classOf steps) != Integer) then ( throw "Wrong input in function getFrontFaces(): steps must be a positive Integer" ) local fDotThresh = 1e-3 local fMatchThresh = 1e-3 local fOffsetThresh = 1e-2 local baFrontFaces = #{} local iNumFaces = 0 local p3FaceCenter = [0,0,0] local p3FaceNormal = [0,0,0] local p3CameraToFaceVect = [0,0,0] local fDotViewAngle = 0.0 local p3CameraPos = (inverse(getViewTM())).row4 local p3CameraViewDir = -(inverse(getViewTM())).row3 local bIsPerspective = viewport.isPerspView() local fObjMaxDim = distance obj.max obj.min -- Editable Poly --------------------------------------------------------------- if ((classOf obj) == Editable_Poly) then ( iNumFaces = polyOp.getNumFaces obj for i = 1 to iNumFaces do ( p3FaceCenter = polyOp.getFaceCenter obj i p3FaceNormal = polyOp.getFaceNormal obj i if (bIsPerspective == true) then ( p3CameraToFaceVect = p3FaceCenter - p3CameraPos fDotViewAngle = dot p3CameraToFaceVect p3FaceNormal ) else ( fDotViewAngle = dot p3CameraViewDir p3FaceNormal ) if (fDotViewAngle < -fDotThresh) then ( baFrontFaces[i] = true ) ) -- set test vert --------------------------------------------------------------- local iNumTestVerts = polyOp.getNumVerts obj local ap3TestVertPos = for i = 1 to iNumTestVerts collect (polyOp.getVert obj i) if (steps > 0) then ( local iNumAllEdges = polyOp.getNumEdges obj local aiEdgeVerts = #() local ap3NewTestPos = #() local p3EdgeVector = [0,0,0] for i = 1 to iNumAllEdges do ( aiEdgeVerts = polyOp.getEdgeVerts obj i for j = 1 to steps do ( p3EdgeVector = ap3TestVertPos[aiEdgeVerts[2]] - ap3TestVertPos[aiEdgeVerts[1]] append ap3NewTestPos (ap3TestVertPos[aiEdgeVerts[1]] + ((p3EdgeVector / (steps +1)) * j) ) ) ) join ap3TestVertPos ap3NewTestPos iNumTestVerts = ap3TestVertPos.count ) -- run test -------------------------------------------------------------------- local ap3CameraToVertDir = #() local rTest = ray [0,0,0] [0,0,0] local rResult = ray [0,0,0] [0,0,0] local aResult = #() local p3RayPos = [0,0,0] local aIterator = #(true) with redraw off ( local oMesh = snapShot obj -- ray from vert away from camera ---------------------------------------------- for i = 1 to iNumTestVerts do ( if (bIsPerspective == true) then ap3CameraToVertDir[i] = normalize(ap3TestVertPos[i] - p3CameraPos) else ap3CameraToVertDir[i] = p3CameraViewDir p3RayPos = ap3TestVertPos[i] + ap3CameraToVertDir[i] * fOffsetThresh aIterator = #(0) for dummy in aIterator do ( rTest = ray p3RayPos ap3CameraToVertDir[i] aResult = intersectRayEx oMesh rTest if (aResult != undefined) then ( baFrontFaces -= #{getPolyFromMeshFace obj aResult[2]} p3RayPos = aResult[1].pos + ap3CameraToVertDir[i] * fOffsetThresh append aIterator 0 ) ) ) baFrontVerts = polyOp.getVertsUsingFace obj baFrontFaces -- ray from camera to vert ----------------------------------------------------- for iVert in baFrontVerts do ( if (bIsPerspective == true) then ( rTest = ray p3CameraPos ap3CameraToVertDir[iVert] ) else ( p3RayPos = ap3TestVertPos[iVert] - p3CameraViewDir * fObjMaxDim rTest = ray p3RayPos p3CameraViewDir ) aResult = intersectRayEx oMesh rTest if (aResult != undefined) then ( if ((posMatch ap3TestVertPos[iVert] aResult[1].pos fMatchThresh) == false) then ( if (distance p3CameraPos aResult[1].pos) < (distance p3CameraPos ap3TestVertPos[iVert]) then ( baFrontFaces -= polyOp.getFacesUsingVert obj iVert ) ) ) ) baFrontVerts = polyOp.getVertsUsingFace obj baFrontFaces -- ray from vert to camera ----------------------------------------------------- for iVert in baFrontVerts do ( if (bIsPerspective == true) then ( p3RayPos = ap3TestVertPos[iVert] - ap3CameraToVertDir[iVert] * fOffsetThresh rTest = ray p3RayPos -ap3CameraToVertDir[iVert] ) else ( p3RayPos = ap3TestVertPos[iVert] - p3CameraViewDir * fOffsetThresh rTest = ray p3RayPos -p3CameraViewDir ) rResult = intersectRay obj rTest if (rResult != undefined) then ( baFrontFaces -= polyOp.getFacesUsingVert obj iVert ) ) delete oMesh ) polyOp.setFaceSelection obj baFrontFaces -- just for visual feedback, remove if not needed ) -- Editable Mesh --------------------------------------------------------------- else if ((classOf obj) == Editable_Mesh) then ( iNumFaces = meshOp.getNumFaces obj for i = 1 to iNumFaces do ( p3FaceCenter = meshOp.getFaceCenter obj i p3FaceNormal = getFaceNormal obj i if (bIsPerspective == true) then ( p3CameraToFaceVect = p3FaceCenter - p3CameraPos fDotViewAngle = dot p3CameraToFaceVect p3FaceNormal ) else ( fDotViewAngle = dot p3CameraViewDir p3FaceNormal ) if (fDotViewAngle < -fDotThresh) then ( baFrontFaces[i] = true ) ) -- set test vert --------------------------------------------------------------- local iNumTestVerts = meshOp.getNumVerts obj local ap3TestVertPos = for i = 1 to iNumTestVerts collect (meshOp.getVert obj i) if (steps > 0) then ( with redraw off ( local oPoly = snapShot obj local iNumAllFaces = meshOp.getNumFaces oPoly for i = 1 to iNumAllFaces do for j = 1 to 3 do setEdgeVis oPoly i j true oPoly = convertToPoly oPoly local iNumAllEdges = polyOp.getNumEdges oPoly local aiEdgeVerts = #() local ap3NewTestPos = #() local p3EdgeVector = [0,0,0] for i = 1 to iNumAllEdges do ( aiEdgeVerts = polyOp.getEdgeVerts oPoly i for j = 1 to steps do ( p3EdgeVector = ap3TestVertPos[aiEdgeVerts[2]] - ap3TestVertPos[aiEdgeVerts[1]] append ap3NewTestPos (ap3TestVertPos[aiEdgeVerts[1]] + ((p3EdgeVector / (steps +1)) * j) ) ) ) join ap3TestVertPos ap3NewTestPos iNumTestVerts = ap3TestVertPos.count delete oPoly ) ) -- run test -------------------------------------------------------------------- local ap3CameraToVertDir = #() local rTest = ray [0,0,0] [0,0,0] local rResult = ray [0,0,0] [0,0,0] local aResult = #() local p3RayPos = [0,0,0] local aIterator = #(true) -- ray from vert away from camera ---------------------------------------------- for i = 1 to iNumTestVerts do ( if (bIsPerspective == true) then ap3CameraToVertDir[i] = normalize(ap3TestVertPos[i] - p3CameraPos) else ap3CameraToVertDir[i] = p3CameraViewDir p3RayPos = ap3TestVertPos[i] + ap3CameraToVertDir[i] * fOffsetThresh aIterator = #(0) for dummy in aIterator do ( rTest = ray p3RayPos ap3CameraToVertDir[i] aResult = intersectRayEx obj rTest if (aResult != undefined) then ( baFrontFaces[aResult[2]] = false p3RayPos = aResult[1].pos + ap3CameraToVertDir[i] * fOffsetThresh append aIterator 0 ) ) ) baFrontVerts = meshOp.getVertsUsingFace obj baFrontFaces -- ray from camera to vert ----------------------------------------------------- for iVert in baFrontVerts do ( if (bIsPerspective == true) then ( rTest = ray p3CameraPos ap3CameraToVertDir[iVert] ) else ( p3RayPos = ap3TestVertPos[iVert] - p3CameraViewDir * fObjMaxDim rTest = ray p3RayPos p3CameraViewDir ) aResult = intersectRayEx obj rTest if (aResult != undefined) then ( if ((posMatch ap3TestVertPos[iVert] aResult[1].pos fMatchThresh) == false) then ( if (distance p3CameraPos aResult[1].pos) < (distance p3CameraPos ap3TestVertPos[iVert]) then ( baFrontFaces -= meshOp.getFacesUsingVert obj iVert ) ) ) ) baFrontVerts = meshOp.getVertsUsingFace obj baFrontFaces -- ray from vert to camera ----------------------------------------------------- for iVert in baFrontVerts do ( if (bIsPerspective == true) then ( p3RayPos = ap3TestVertPos[iVert] - ap3CameraToVertDir[iVert] * fOffsetThresh rTest = ray p3RayPos -ap3CameraToVertDir[iVert] ) else ( p3RayPos = ap3TestVertPos[iVert] - p3CameraViewDir * fOffsetThresh rTest = ray p3RayPos -p3CameraViewDir ) rResult = intersectRay obj rTest if (rResult != undefined) then ( baFrontFaces -= meshOp.getFacesUsingVert obj iVert ) ) setFaceSelection obj baFrontFaces -- just for visual feedback, remove if not needed ) -- Neither Editable Poly, nor Editable Mesh ------------------------------------ else ( throw "Wrong input in function getFrontFaces()" ) return baFrontFaces )
Get Front Faces <BitArray faceList> getFrontFacesByCenters <Editable_Poly | Editable_Mesh node> Returns a list of faces whose center point is not occluded, with normal facing camera direction. For Editable Polys, a face is considered not occluded only if the centers of all triangles constituting it are not occluded.
Required functions: getPolyFromMeshFace() found under: "Editable Poly data from underlying Mesh"
function posMatch pA pB fT = ( if ((classOf pA == Point3) and (classOf pB == Point3) and (classOf fT == Float)) then ( return (((abs(pA.x - pB.x)) < fT) and ((abs(pA.y - pB.y)) < fT) and ((abs(pA.z - pB.z)) < fT)) ) else ( throw "Wrong input in function posMatch()" ) ) -------------------------------------------------------------------------------- function getFrontFacesByCenters obj = ( local fDotThresh = 1e-3 local fMatchThresh = 1e-3 local fOffsetThresh = 1e-2 local baFrontFaces = #{} local iNumFaces = 0 local ap3FaceCenter = #() local p3FaceNormal = [0,0,0] local p3CameraToFaceVect = [0,0,0] local fDotViewAngle = 0.0 local p3CameraPos = (inverse(getViewTM())).row4 local p3CameraViewDir = -(inverse(getViewTM())).row3 local bIsPerspective = viewport.isPerspView() local fObjMaxDim = distance obj.max obj.min -- Editable Poly --------------------------------------------------------------- if ((classOf obj) == Editable_Poly) then ( iNumFaces = polyOp.getNumFaces obj for i = 1 to iNumFaces do ( ap3FaceCenter[i] = polyOp.getFaceCenter obj i p3FaceNormal = polyOp.getFaceNormal obj i if (bIsPerspective == true) then ( p3CameraToFaceVect = ap3FaceCenter[i] - p3CameraPos fDotViewAngle = dot p3CameraToFaceVect p3FaceNormal ) else ( fDotViewAngle = dot p3CameraViewDir p3FaceNormal ) if (fDotViewAngle < -fDotThresh) then ( baFrontFaces[i] = true ) ) with redraw off ( local p3MeshFaceCenter = [0,0,0] local p3CameraToCentDir = [0,0,0] local p3TestPos = [0,0,0] local rTest = ray [0,0,0] [0,0,0] local rResult = ray [0,0,0] [0,0,0] local oMesh = snapShot obj local baFrontVert = polyOp.getVertsUsingFace obj baFrontFaces local baMeshFaces = meshOp.getFacesUsingVert oMesh baFrontVert -- ray from camera to mesh face center ----------------------------------------- for iFace in baMeshFaces do ( p3MeshFaceCenter = meshOp.getFaceCenter oMesh iFace if (bIsPerspective == true) then ( p3CameraToCentDir = normalize(p3MeshFaceCenter - p3CameraPos) rTest = ray p3CameraPos p3CameraToCentDir rResult = intersectRay oMesh rTest if (rResult != undefined) then if ((posMatch p3MeshFaceCenter rResult.pos fMatchThresh) == false) then if ((distance p3CameraPos rResult.pos) < (distance p3CameraPos p3MeshFaceCenter)) then baMeshFaces[iFace] = false ) else ( p3TestPos = p3MeshFaceCenter - p3CameraViewDir * fObjMaxDim rTest = ray p3TestPos p3CameraViewDir rResult = intersectRay oMesh rTest if (rResult != undefined) then if ((posMatch p3MeshFaceCenter rResult.pos fMatchThresh) == false) then baMeshFaces[iFace] = false ) ) local baPolyFromMesh = #{} for iFace in baMeshFaces do ( baPolyFromMesh[getPolyFromMeshFace obj iFace] = true baMeshFaces -= meshOp.getPolysUsingFace oMesh iFace ignoreVisEdges:false threshhold:120 ) delete oMesh baFrontFaces *= baPolyFromMesh -- ray from face center to camera ---------------------------------------------- for iFace in baFrontFaces do ( if (bIsPerspective == true) then ( p3CameraToCentDir = normalize(ap3FaceCenter[iFace] - p3CameraPos) rTest = ray (ap3FaceCenter[iFace] - p3CameraToCentDir * fOffsetThresh) -p3CameraToCentDir ) else ( rTest = ray (ap3FaceCenter[iFace] - p3CameraViewDir * fOffsetThresh) -p3CameraViewDir ) rResult = intersectRay obj rTest if (rResult != undefined) then baFrontFaces[iFace] = false ) ) polyOp.setFaceSelection obj baFrontFaces -- just for visual feedback, remove if not needed ) -- Editable Mesh --------------------------------------------------------------- else if ((classOf obj) == Editable_Mesh) then ( iNumFaces = meshOp.getNumFaces obj for i = 1 to iNumFaces do ( ap3FaceCenter[i] = meshOp.getFaceCenter obj i p3FaceNormal = getFaceNormal obj i if (bIsPerspective == true) then ( p3CameraToFaceVect = ap3FaceCenter[i] - p3CameraPos fDotViewAngle = dot p3CameraToFaceVect p3FaceNormal ) else ( fDotViewAngle = dot p3CameraViewDir p3FaceNormal ) if (fDotViewAngle < -fDotThresh) then ( baFrontFaces[i] = true ) ) local ap3CameraToCentDir = #() local p3TestPos = [0,0,0] local rTest = ray [0,0,0] [0,0,0] local rResult = ray [0,0,0] [0,0,0] -- ray from camera to mesh face center ----------------------------------------- for iFace in baFrontFaces do ( if (bIsPerspective == true) then ( ap3CameraToCentDir[iFace] = normalize(ap3FaceCenter[iFace] - p3CameraPos) rTest = ray p3CameraPos ap3CameraToCentDir[iFace] rResult = intersectRay obj rTest if (rResult != undefined) then if ((posMatch ap3FaceCenter[iFace] rResult.pos fMatchThresh) == false) then if ((distance p3CameraPos rResult.pos) < (distance p3CameraPos ap3FaceCenter[iFace])) then baFrontFaces[iFace] = false ) else ( p3TestPos = ap3FaceCenter[iFace] - p3CameraViewDir * fObjMaxDim rTest = ray p3TestPos p3CameraViewDir rResult = intersectRay obj rTest if (rResult != undefined) then if ((posMatch ap3FaceCenter[iFace] rResult.pos fMatchThresh) == false) then baFrontFaces[iFace] = false ) ) -- ray from face center to camera ---------------------------------------------- for iFace in baFrontFaces do ( if (bIsPerspective == true) then rTest = ray (ap3FaceCenter[iFace] - ap3CameraToCentDir[iFace] * fOffsetThresh) -ap3CameraToCentDir[iFace] else rTest = ray (ap3FaceCenter[iFace] - p3CameraViewDir * fOffsetThresh) -p3CameraViewDir rResult = intersectRay obj rTest if (rResult != undefined) then baFrontFaces[iFace] = false ) setFaceSelection obj baFrontFaces -- just for visual feedback, remove if not needed ) -- Neither Editable Poly, nor Editable Mesh ------------------------------------ else ( throw "Wrong input in function getFrontFacesByCenters()" ) return baFrontFaces )