-- -- File:: pipeline/util/MeshUtil.ms -- Description:: Set of functions for interacting with meshes -- -- 23/6/2004 -- by Greg Smith -- ----------------------------------------------------------------------------- -- Returns lowest vert (in world-space) in obj: fn RsGetLowestVert obj = ( local copiedMesh = not isKindOf obj EditableMesh local objMesh = if copiedMesh then (copy obj.mesh) else obj.mesh local minZ local minVert = dataPair idx:undefined pos:undefined for n = 1 to getNumVerts objMesh do ( local vertPos = getVert objMesh n if copiedMesh do ( vertPos *= obj.transform ) if (minZ == undefined) or (vertPos.z < minZ) do ( minZ = vertPos.z minVert.pos = vertPos minVert.idx = n ) ) return minVert ) mapped fn RSmoveToGround objA objB percentMin percentMax = ( if (not isProperty objA "mesh") or (not isProperty objB "mesh") do (return False) local objAMesh = if (isKindOf objA EditableMesh) then objA.mesh else (copy objA.mesh) local objBMesh = if (isKindOf objB EditableMesh) then objB.mesh else (copy objB.mesh) local lowestVert = RsGetLowestVert objA local testRay = ray lowestVert.pos [0,0,-1] local intersect = intersectRay objB testRay if (intersect != undefined) do ( local rand_offset = random percentMin percentMax local startRot = objA.rotation local objRotZ = (startRot as eulerangles).z -- MATCH THE DIRECTION local directionOffset = intersect.dir - objA.dir -- PERCENT OF ANGLE MATCH * GROUND ANGLE objA.dir = intersect.dir - (directionOffset * ((100-rand_offset)/100.0)) local newRot = objA.rotation as eulerangles newRot.z = objRotZ objA.rotation = newRot -- Update lowest-vert pos to rotated position: lowestVert.pos = (getVert objA.mesh lowestVert.idx) * objA.transform local moveVec = intersect.pos - lowestVert.pos local setPos = objA.pos + moveVec objA.pos = setPos ) ) -- --fn: RSFindFacesWithZeroArea --desc: Finds any faces on a editable mesh or poly with 0 area -- and deletes them (which deletes the verts) -- -- returns true if the faces are deleted, or the array of faces -- with zero area if deleteFaces is false. -- fn RSFindFacesWithZeroArea obj deleteFaces:false = ( facesToDelete = #() if ( Editable_Mesh == classof obj ) then ( for f = ( meshop.getNumFaces obj ) to 1 by -1 do ( if ( meshop.getFaceArea obj f == 0 ) do ( append facesToDelete f ) ) if ( true == deleteFaces) then ( meshop.deleteFaces obj facesToDelete true ) else ( facesToDelete ) ) else if ( Editable_Poly == classof obj ) do ( for f = ( polyop.getNumFaces obj ) to 1 by -1 do ( if ( polyop.getFaceArea obj f == 0 ) do ( append facesToDelete f ) ) if ( true == deleteFaces) then ( polyop.deleteFaces obj facesToDelete true ) else ( facesToDelete ) ) ) fn RsTestFaceForVertIndex face index = ( case index of ( (face[1]):1 (face[2]):2 (face[3]):3 default:0 ) ) fn RsGetColourAverageForMeshVertIndex theMesh theChannel meshVertIndex = ( local faces = (meshop.getFacesUsingVert theMesh #{meshVertIndex}) as array local indeces = #() local mapindeces = #() local averagedValue = [0,0,0] for f in faces do ( append indeces (getFace theMesh f) append mapindeces (meshop.getMapFace theMesh theChannel f) ) for index=1 to 3 do ( -- local vertindex = indeces[1][index] local meshVertIndeces = #() local isShared = true for indexVectorIndex=1 to indeces.count do ( local indexVector = indeces[indexVectorIndex] local sharedvertFaceIndex = RsTestFaceForVertIndex indexVector meshVertIndex append meshVertIndeces sharedvertFaceIndex if 0 == sharedvertFaceIndex then isShared = false ) -- We found the shared index in the faces -- Now take face indeces and get map verteces with those if isShared then ( for indexVectorIndex=1 to mapindeces.count do ( local sharedvertindex = meshVertIndeces[indexVectorIndex] local index = mapindeces[indexVectorIndex][sharedvertindex] local vertValue = meshop.getMapVert theMesh theChannel index averagedValue = averagedValue + vertValue ) averagedValue /= mapindeces.count exit ) ) return averagedValue )