def boundingBox(self): """ Returns the bounding box for the shape. In this case just use the radius and height attributes to determine the bounding box. """ result = OpenMaya.MBoundingBox() geom = self.geometry() # Include the instance shape bounding box if geom.instanceShape: fnDag = OpenMaya.MFnDagNode(geom.instanceShape) result = fnDag.boundingBox() r = geom.radius instanceBbox = OpenMaya.MBoundingBox(result) for c in range(geom.count): percent = float(c) / float(geom.count) rad = 2 * math.pi * percent p = (r * math.cos(rad), r * math.sin(rad), 0.0) newbbox = OpenMaya.MBoundingBox(instanceBbox) trans = OpenMaya.MTransformationMatrix() vec = OpenMaya.MVector(p[0], p[1], p[2]) trans.setTranslation(vec, OpenMaya.MSpace.kTransform) mmatrix = trans.asMatrix() newbbox.transformUsing(mmatrix) result.expand(newbbox) return result
def loadSelectedStartIndices(*args): import sgBFunction_dag mesh, indices = sgBFunction_mesh.getMeshAndIndicesPoints(cmds.ls(sl=1)) cmds.textField(Window_Global.fld_targetMesh, e=1, tx=mesh) indicesStr = '' for i in indices: indicesStr += str(i) + ',' cmds.textField(Window_Global.fld_startPoints, e=1, tx=indicesStr[:-1]) fnMesh = om.MFnMesh(sgBFunction_dag.getMDagPath(mesh)) points = om.MPointArray() fnMesh.getPoints(points) bb = om.MBoundingBox() for i in range(len(indices)): bb.expand(points[indices[i]]) center = om.MPoint(bb.center()) farIndex = 0 farDist = 0.0 for i in range(points.length()): dist = center.distanceTo(points[i]) if farDist < dist: farDist = dist farIndex = i print farIndex cmds.textField(Window_Global.fld_endPoints, e=1, tx=str(farIndex))
def geometryBoundingBox(geometry,worldSpace=True,noIntermediate=True,visibleOnly=True): ''' Get an accurate bounding box from the geometry shapes under the specified geometry (transform or group). @param geometry: Geometry to return accurate bounding box for @type geometry: str or list ''' # Initialize Object Classes geoDagPath = OpenMaya.MDagPath() selectionList = OpenMaya.MSelectionList() # Initialize empty bounding box bbox = OpenMaya.MBoundingBox() # Get Visible Geometry (Shapes) geoShapes = mc.ls(mc.listRelatives(geometry,ad=True,pa=True),noIntermediate=noIntermediate,geometry=True,visible=visibleOnly) # Expand Bounding Box for shape in geoShapes: selectionList.clear() OpenMaya.MGlobal.getSelectionListByName(shape,selectionList) selectionList.getDagPath(0,geoDagPath) bboxShape = OpenMaya.MFnDagNode(geoDagPath).boundingBox() if worldSpace: bboxShape.transformUsing(geoDagPath.inclusiveMatrix()) bbox.expand(bboxShape) # Get Bounding Box Min/Max (as MPoint) mn = bbox.min() mx = bbox.max() # Return Formatted Result return [mn.x,mn.y,mn.z,mx.x,mx.y,mx.z]
def boundingBox(self): # get the tPositions tPositions = self.getTPositions() # get the multiplier size = self.getSize() # create the bounding box bbox = OpenMaya.MBoundingBox() # add the positions one by one numOfTPos = tPositions.length() #print("numOfTPos in bbox : %s " % numOfTPos) for i in range(numOfTPos): # add the positive one bbox.expand( OpenMaya.MPoint( tPositions[i] + OpenMaya.MVector(size, size, size) ) ) # add the negative one bbox.expand( OpenMaya.MPoint( tPositions[i] - OpenMaya.MVector(size, size, size) ) ) return bbox
def getSurfaceCenterCurve(surface, multMatrix=False): fnSurface = om.MFnNurbsSurface(fnc.getMObject(surface)) if multMatrix: surfaceMatrix = fnc.getMMatrixFromMtxList(cmds.getAttr(surface + '.wm')) else: surfaceMatrix = om.MMatrix() degreeU = fnSurface.degreeU() numU = fnSurface.numCVsInU() numV = fnSurface.numCVsInV() cvPoints = [] for i in range(numU): bbox = om.MBoundingBox() point = om.MPoint() for j in range(numV): fnSurface.getCV(i, j, point) bbox.expand(point) minPoint = om.MVector(bbox.min()) maxPoint = om.MVector(bbox.max()) cPoint = om.MPoint((minPoint + maxPoint) / 2) * surfaceMatrix cvPoints.append([cPoint.x, cPoint.y, cPoint.z]) return cmds.curve(p=cvPoints, d=degreeU)
def findClosestFacePosition(position, mesh): meshMatrix = cmds.getAttr(mesh + '.wm') mMeshMatrix = om.MMatrix() om.MScriptUtil.createMatrixFromList(meshMatrix, mMeshMatrix) intersector = om.MMeshIntersector() mPoint = om.MPoint(*position) mPoint *= mMeshMatrix.inverse() pointOnMesh = om.MPointOnMesh() intersector.create(getMObject(mesh)) intersector.getClosestPoint(mPoint, pointOnMesh) fnMesh = om.MFnMesh(getMObject(mesh)) verticesArr = om.MIntArray() fnMesh.getPolygonVertices(pointOnMesh.faceIndex(), verticesArr) boundingBox = om.MBoundingBox() for i in range(verticesArr.length()): point = om.MPoint() fnMesh.getPoint(verticesArr[i], point) boundingBox.expand(point) center = boundingBox.center() center *= mMeshMatrix return center.x, center.y, center.z
def getComponentBBox(cls, components): """ @param[in] components: faces that are used for computing their common bounding box @type components: list of faces @returns: MBoundingBox of the passed in components """ cmds.select(components) objectList = OpenMaya.MSelectionList() objectList.clear() OpenMaya.MGlobal.getActiveSelectionList(objectList) #get active selection list dagPath = OpenMaya.MDagPath() component = OpenMaya.MObject() objectList.getDagPath(0, dagPath, component) iter = OpenMaya.MItMeshPolygon(dagPath, component) bbox = OpenMaya.MBoundingBox() while not iter.isDone(): pointArray = OpenMaya.MPointArray() iter.getPoints(pointArray, OpenMaya.MSpace.kWorld) for i in range(0, pointArray.length()): bbox.expand(OpenMaya.MPoint(pointArray[i].x, pointArray[i].y, pointArray[i].z)) iter.next() return bbox
def getTubeIntersectionPointAndNormal( tubeMesh, baseMesh ): import math import sgBFunction_dag hairMesh = tubeMesh headMesh = baseMesh headMeshShape = sgBFunction_dag.getShape( headMesh ) dagPathHead = sgBFunction_dag.getMDagPath( headMeshShape ) intersector = om.MMeshIntersector() intersector.create( dagPathHead.node() ) hairMeshShape = sgBFunction_dag.getShape( hairMesh ) dagPathHairMesh = sgBFunction_dag.getMDagPath( hairMeshShape ) fnMesh = om.MFnMesh( dagPathHairMesh ) points = om.MPointArray() fnMesh.getPoints( points ) pointOnMesh = om.MPointOnMesh() minDist = 100000.0 minDistIndex = 0 minDistNormal = om.MVector() for i in range( points.length() ): intersector.getClosestPoint( points[i], pointOnMesh ) closePoint = om.MPoint( pointOnMesh.getPoint() ) dist = closePoint.distanceTo( points[i] ) if dist < minDist: normal = om.MVector() itNormal = om.MVector( pointOnMesh.getNormal() ) fnMesh.getVertexNormal( i, True, normal ) if math.fabs( itNormal.normal() * normal.normal() ) < 0.4: minDist = dist minDistIndex = i minDistNormal = itNormal pointMinDist = points[ minDistIndex ] normalMinDist = om.MVector() fnMesh.getVertexNormal( minDistIndex, True, normalMinDist ) srcPoint = om.MPoint( pointMinDist + normalMinDist ) ray = -normalMinDist intersectPoints = om.MPointArray() fnMesh.intersect( srcPoint, ray, intersectPoints ) if intersectPoints.length() == 1: return intersectPoints[0], minDistNormal else: bb = om.MBoundingBox() for k in range( intersectPoints.length() ): bb.expand( intersectPoints[k] ) return bb.center(), minDistNormal
def boundingBox(self): fnThisNode = OpenMaya.MFnDependencyNode(self.thisMObject()) rad = OpenMaya.MPlug(self.thisMObject(), fnThisNode.attribute("radius")).asFloat() corner1 = OpenMaya.MPoint(rad, rad, rad) corner2 = OpenMaya.MPoint(-rad, -rad, -rad) bbox = OpenMaya.MBoundingBox(corner1, corner2) return bbox
def getBoundingBox(self, mMeshObj): mPointArray = OpenMaya.MPointArray() mMeshObj.getPoints(mPointArray, OpenMaya.MSpace.kTransform) BBox = OpenMaya.MBoundingBox() for i in range(mPointArray.length()): BBox.expand(mPointArray[i]) return BBox
def boundingBox(self): bbox = OpenMaya.MBoundingBox() bbox.expand( OpenMaya.MPoint(-self.displayRadius, -self.displayRadius, -self.displayRadius)) bbox.expand( OpenMaya.MPoint(self.displayRadius, self.displayRadius, self.displayRadius)) return bbox
def boundingBox(self): bbox = OpenMaya.MBoundingBox() bbox.expand(OpenMaya.MPoint(-0.5, 0.0, -0.5)) bbox.expand(OpenMaya.MPoint(0.5, 0.0, -0.5)) bbox.expand(OpenMaya.MPoint(0.5, 0.0, 0.5)) bbox.expand(OpenMaya.MPoint(-0.5, 0.0, 0.5)) bbox.expand(OpenMaya.MPoint(0.0, -0.5, 0.0)) bbox.expand(OpenMaya.MPoint(0.0, 0.5, 0.0)) return bbox
def create(*args): strTargetMesh = cmds.textField(Window_Global.fld_targetMesh, q=1, tx=1) strIndicesStart = cmds.textField(Window_Global.fld_startPoints, q=1, tx=1) strIndicesEnd = cmds.textField(Window_Global.fld_endPoints, q=1, tx=1) detail = cmds.intField(Window_Global.fld_detail, q=1, v=1) eStrStartIndices = strIndicesStart.split(',') eStrEndIndices = strIndicesEnd.split(',') indicesStart = [] for strIndex in eStrStartIndices: indicesStart.append(int(strIndex.strip())) indicesEnd = [] for strIndex in eStrEndIndices: indicesEnd.append(int(strIndex.strip())) import sgBFunction_dag dagPathMesh = sgBFunction_dag.getMDagPath(strTargetMesh) fnMesh = om.MFnMesh(dagPathMesh) pointsMesh = om.MPointArray() fnMesh.getPoints(pointsMesh) bbStarts = om.MBoundingBox() bbEnds = om.MBoundingBox() for index in indicesStart: bbStarts.expand(pointsMesh[index]) for index in indicesEnd: bbEnds.expand(pointsMesh[index]) startCenter = bbStarts.center() * dagPathMesh.inclusiveMatrix() endCenter = bbEnds.center() * dagPathMesh.inclusiveMatrix() sgBFunction_mesh.createJointLineFromMeshApi(dagPathMesh, startCenter, endCenter, detail)
def createCurveFromMesh(meshName, centerIndices, startIndex, endIndices, numSample=20): bb = om.MBoundingBox() for i in centerIndices: point = om.MPoint( *cmds.xform(meshName + '.vtx[%d]' % i, q=1, ws=1, t=1)) bb.expand(point) centerPoint = bb.center() bb = om.MBoundingBox() for i in endIndices: point = om.MPoint( *cmds.xform(meshName + '.vtx[%d]' % i, q=1, ws=1, t=1)) bb.expand(point) endPoint = bb.center() startPoint = om.MPoint( *cmds.xform(meshName + '.vtx[%d]' % startIndex, q=1, ws=1, t=1)) aimVector = om.MVector(endPoint) - om.MVector(startPoint) eachPoints = [] multRate = 1.0 / (numSample - 1) for i in range(numSample): eachPoint = aimVector * (multRate * i) + om.MVector(centerPoint) eachPoints.append(om.MPoint(eachPoint)) fnMesh = getMFnMesh(meshName) mtx = fnMesh.dagPath().inclusiveMatrix() mtxInv = mtx.inverse() intersector = om.MMeshIntersector() intersector.create(fnMesh.object()) pointOnMesh = om.MPointOnMesh() for point in eachPoints: intersector.getClosestPoint(point * mtxInv, pointOnMesh) closePoint = om.MPoint(pointOnMesh.getPoint()) * mtx cmds.spaceLocator(p=[closePoint.x, closePoint.y, closePoint.z])
def boundingBox(self): fnThisNode = OpenMaya.MFnDependencyNode(self.thisMObject()) xsize = OpenMaya.MPlug(self.thisMObject(), fnThisNode.attribute("xsize")).asFloat() ysize = OpenMaya.MPlug(self.thisMObject(), fnThisNode.attribute("ysize")).asFloat() zsize = OpenMaya.MPlug(self.thisMObject(), fnThisNode.attribute("zsize")).asFloat() corner1 = OpenMaya.MPoint(xsize, ysize, zsize) corner2 = OpenMaya.MPoint(-xsize, -ysize, -zsize) bbox = OpenMaya.MBoundingBox(corner1, corner2) return bbox
def getBoundingBox(self, pMeshObj): '''Calculate a bounding box around the mesh's vertices.''' boundingBox = OpenMaya.MBoundingBox() meshFn = OpenMaya.MFnMesh(pMeshObj) pointArray = OpenMaya.MPointArray() # Get the points of the mesh in its local coordinate space. meshFn.getPoints(pointArray, OpenMaya.MSpace.kTransform) for i in xrange(pointArray.length()): boundingBox.expand(pointArray[i]) return boundingBox
def getBoundingBoxMinMaxY( selObject ): bb = OpenMaya.MBoundingBox() bbmin = cmds.getAttr( selObject + '.boundingBoxMin' )[0] bbmax = cmds.getAttr( selObject + '.boundingBoxMax' )[0] multMatrix = Tool_global.randomMatrix * Tool_global.scaleEditMatrix point1 = OpenMaya.MPoint( bbmin[0], bbmin[1], bbmin[2] ) * multMatrix point2 = OpenMaya.MPoint( bbmax[0], bbmin[1], bbmin[2] ) * multMatrix point3 = OpenMaya.MPoint( bbmax[0], bbmax[1], bbmin[2] ) * multMatrix point4 = OpenMaya.MPoint( bbmax[0], bbmax[1], bbmax[2] ) * multMatrix point5 = OpenMaya.MPoint( bbmin[0], bbmax[1], bbmax[2] ) * multMatrix point6 = OpenMaya.MPoint( bbmin[0], bbmin[1], bbmax[2] ) * multMatrix bb.expand( point1 ); bb.expand( point2 ); bb.expand( point3 ) bb.expand( point4 ); bb.expand( point5 ); bb.expand( point6 ) return bb.min().y, bb.max().y
def isBounded(self): return True def boundingBox(self): thisNode = self.thisMObject() plug = OpenMaya.MPlug(thisNode, swissArmyLocator.aSize) sizeVal = plug.asMDistance() multiplier = sizeVal.asCentimeters() corner1 = OpenMaya.MPoint(-1.1, 0.0, -1.1) corner2 = OpenMaya.MPoint(1.1, 0.0, 1.1)
def getAlignedBoundsForJoint(joint, threshold=0.65, onlyVisibleMeshes=True): ''' looks at the verts the given joint/s and determines a local space (local to the first joint in the list if multiple are given) bounding box of the verts, and positions the hitbox accordingly if onlyVisibleMeshes is True, then only meshes that are visible in the viewport will contribute to the bounds ''' theJoint = joint verts = [] #so this is just to deal with the input arg being a tuple, list or string. you can pass in a list #of joint names and the verts affected just get accumulated into a list, and the resulting bound #should be the inclusive bounding box for the given joints if isinstance(joint, (tuple, list)): theJoint = joint[0] for joint in joint: verts += jointVertsForMaya(joint, threshold, onlyVisibleMeshes) else: verts += jointVertsForMaya(joint, threshold, onlyVisibleMeshes) jointDag = api.getMDagPath(theJoint) jointMatrix = jointDag.inclusiveMatrix() vJointPos = OpenMaya.MTransformationMatrix(jointMatrix).rotatePivot( OpenMaya.MSpace.kWorld) + OpenMaya.MTransformationMatrix( jointMatrix).getTranslation(OpenMaya.MSpace.kWorld) vJointPos = Vector([vJointPos.x, vJointPos.y, vJointPos.z]) vJointBasisX = OpenMaya.MVector(-1, 0, 0) * jointMatrix vJointBasisY = OpenMaya.MVector(0, -1, 0) * jointMatrix vJointBasisZ = OpenMaya.MVector(0, 0, -1) * jointMatrix bbox = OpenMaya.MBoundingBox() for vert in verts: #get the position relative to the joint in question vPos = Vector(xform(vert, query=True, ws=True, t=True)) vPos = vJointPos - vPos #now transform the joint relative position into the coordinate space of that joint #we do this so we can get the width, height and depth of the bounds of the verts #in the space oriented along the joint vPosInJointSpace = Vector((vPos.x, vPos.y, vPos.z)) vPosInJointSpace = vPosInJointSpace.change_space( vJointBasisX, vJointBasisY, vJointBasisZ) bbox.expand(OpenMaya.MPoint(*vPosInJointSpace)) minB, maxB = bbox.min(), bbox.max() return minB[0], minB[1], minB[2], maxB[0], maxB[1], maxB[2]
def boundingBox(self): corner1 = OpenMaya.MPoint(doubleArrowVerts[1][0], doubleArrowVerts[1][1], doubleArrowVerts[1][2]) corner2 = OpenMaya.MPoint(doubleArrowVerts[6][0], doubleArrowVerts[6][1], doubleArrowVerts[6][2]) bbox = OpenMaya.MBoundingBox(corner1, corner2) bbox.expand( OpenMaya.MPoint(doubleArrowVerts[0][0], doubleArrowVerts[0][1], doubleArrowVerts[0][2])) bbox.expand( OpenMaya.MPoint(doubleArrowVerts[5][0], doubleArrowVerts[5][1], doubleArrowVerts[5][2])) return bbox
def centerPoint_geometric(ptList): """ Calculate the geometric center of the specified point list @param ptList: List of points to calculate the geometric center from @type ptList: list """ # Calculate Center (Geometric/BoundingBox) bbox = OpenMaya.MBoundingBox() for pt in ptList: pos = glTools.utils.base.getPosition(pt) bbox.expand(OpenMaya.MPoint(pos[0], pos[1], pos[2], 1.0)) cntPt = bbox.center() # Return Result return [cntPt.x, cntPt.y, cntPt.z]
def boundingBox(self): thisNode = self.thisMObject() plug = OpenMaya.MPlug(thisNode, self.size) sizeVal = plug.asMDistance() multiplier = sizeVal.asCentimeters() corner1 = OpenMaya.MPoint(-0.17, 0.0, -0.7) corner2 = OpenMaya.MPoint(0.17, 0.0, 0.3) corner1 = corner1 * multiplier corner2 = corner2 * multiplier bbox = OpenMaya.MBoundingBox(corner1, corner2) return bbox
def getSurfaceUDistance(surface, multMatrix=False): fnSurface = om.MFnNurbsSurface(fnc.getMObject(surface)) if multMatrix: surfaceMatrix = fnc.getMMatrixFromMtxList(cmds.getAttr(surface + '.wm')) else: surfaceMatrix = om.MMatrix() degreeU = fnSurface.degreeU() numSpansU = fnSurface.numSpansInU() numU = fnSurface.numCVsInU() numV = fnSurface.numCVsInV() cvPoints = om.MPointArray() cvPoints.setLength(numU) knots = om.MDoubleArray() knots.setLength(numU + degreeU - 1) for i in range(numU): bbox = om.MBoundingBox() point = om.MPoint() for j in range(numV): fnSurface.getCV(i, j, point) bbox.expand(point) minPoint = om.MVector(bbox.min()) maxPoint = om.MVector(bbox.max()) cPoint = om.MPoint((minPoint + maxPoint) / 2) * surfaceMatrix cvPoints.set(cPoint, i) for i in range(numU + degreeU - 1): if i < degreeU - 1: knots[i] = 0 elif i - degreeU + 1 > numSpansU: knots[i] = numSpansU else: knots[i] = i - degreeU + 1 curveData = om.MFnNurbsCurveData() createCurveObj = curveData.create() fnCreateCurve = om.MFnNurbsCurve() fnCreateCurve.create(cvPoints, knots, degreeU, om.MFnNurbsCurve.kOpen, 0, 0, createCurveObj) fnCurve = om.MFnNurbsCurve(createCurveObj) return fnCurve.length()
def calcBoundingBox(ptList): """ Return bounding box that contains the specified list of points. @param ptList: Geometry to return bounding box for @type ptList: str """ # Initialize Bounding Box bbox = OpenMaya.MBoundingBox() # Add Points for pt in ptList: # Get MPoint mpt = glTools.utils.base.getMPoint(pt) # Expand BoundingBox if not bbox.contains(mpt): bbox.expand(mpt) # Return Result return bbox
def getBoundingBox(self, pMeshObj, pBoundingBoxScale): ''' Calculate a bounding box around the mesh's vertices. ''' # Create the bounding box object we will populate with the points of the mesh. boundingBox = OpenMaya.MBoundingBox() meshFn = OpenMaya.MFnMesh(pMeshObj) pointArray = OpenMaya.MPointArray() # Get the points of the mesh in its local coordinate space. meshFn.getPoints(pointArray, OpenMaya.MSpace.kTransform) for i in range(0, pointArray.length()): point = pointArray[i] boundingBox.expand(point) # Expand the bounding box according to the scaling factor. newMinPoint = boundingBox.min() * pBoundingBoxScale newMaxPoint = boundingBox.max() * pBoundingBoxScale boundingBox.expand(newMinPoint) boundingBox.expand(newMaxPoint) return boundingBox
def boundingBox(self): """ Returns the bounding box for the shape. In this case just use the radius and height attributes to determine the bounding box. """ result = OpenMaya.MBoundingBox() geom = self.geometry() r = geom.radius result.expand(OpenMaya.MPoint(r, r, r)) result.expand(OpenMaya.MPoint(-r, -r, -r)) r = geom.height / 2.0 result.expand(OpenMaya.MPoint(r, r, r)) result.expand(OpenMaya.MPoint(-r, -r, -r)) r = geom.width / 2.0 result.expand(OpenMaya.MPoint(r, r, r)) result.expand(OpenMaya.MPoint(-r, -r, -r)) return result
def averageNormal( *args ): for dagPath, vtxList in selectedVertices(): fnMesh = OpenMaya.MFnMesh( dagPath ) points = OpenMaya.MPointArray() normals = OpenMaya.MFloatVectorArray() fnMesh.getPoints( points ) fnMesh.getVertexNormals( True, normals ) itMeshVtx = OpenMaya.MItMeshVertex( dagPath ) resultPoints = [] for i in range( vtxList.length() ): pPrevIndex = getIntPtr() itMeshVtx.setIndex( vtxList[i], pPrevIndex ) conVertices = OpenMaya.MIntArray(); itMeshVtx.getConnectedVertices(conVertices) bb = OpenMaya.MBoundingBox() for j in range( conVertices.length() ): bb.expand( points[conVertices[j]] ) center = bb.center() centerVector = points[ vtxList[i] ] - center normal = normals[ vtxList[i] ] normal.normalize() projVector = normal * ( normal * OpenMaya.MFloatVector(centerVector) ) resultPoint = -OpenMaya.MVector(projVector)/3.0 + OpenMaya.MVector( points[ vtxList[i] ] ) resultPoints.append( resultPoint ) meshName = fnMesh.partialPathName() for i in range( vtxList.length() ): cmds.move( resultPoints[i].x, resultPoints[i].y, resultPoints[i].z, meshName + ".vtx[%d]" % vtxList[i], os=1 )
def boundingBox(self): fnThisNode = OpenMaya.MFnDependencyNode(self.thisMObject()) sa = OpenMaya.MPlug(self.thisMObject(), fnThisNode.attribute("startAngle")).asFloat() ea = OpenMaya.MPlug(self.thisMObject(), fnThisNode.attribute("endAngle")).asFloat() divs = OpenMaya.MPlug(self.thisMObject(), fnThisNode.attribute("divisions")).asInt() h = OpenMaya.MPlug(self.thisMObject(), fnThisNode.attribute("height")).asFloat() sa, ea = math.radians(sa), math.radians(ea) phi = sa + (ea - sa) r = phi / (2 * math.pi) x = r * math.sin(phi) z = r * math.cos(phi) y = h corner1 = OpenMaya.MPoint(x, y, z) corner2 = OpenMaya.MPoint(-x, 0, -z) corner3 = OpenMaya.MPoint(z, y, x) corner4 = OpenMaya.MPoint(-z, 0, -x) bbox = OpenMaya.MBoundingBox(corner1, corner2) bbox.expand(corner3) bbox.expand(corner4) return bbox
def deform(self, block, geoItr, matrix, index): #get ENVELOPE envelope = OpenMayaMPx.cvar.MPxGeometryFilter_envelope envelopeHandle = block.inputValue(envelope) envelopeVal = envelopeHandle.asFloat() if envelopeVal != 0: #get COLLIDER MESH (as worldMesh) colliderHandle = block.inputValue(self.collider) inColliderMesh = colliderHandle.asMesh() if not inColliderMesh.isNull(): #get collider fn mesh inColliderFn = OpenMaya.MFnMesh(inColliderMesh) #get DEFORMED MESH inMesh = self.get_input_geom(block, index) #get COLLIDER WORLD MATRIX to convert the bounding box to world space colliderMatrixHandle = block.inputValue(self.colliderMatrix) colliderMatrixVal = colliderMatrixHandle.asMatrix() #get BOUNDING BOX MIN VALUES colliderBoundingBoxMinHandle = block.inputValue( self.colliderBoundingBoxMin) colliderBoundingBoxMinVal = colliderBoundingBoxMinHandle.asFloat3( ) #get BOUNDING BOX MAX VALUES colliderBoundingBoxMaxHandle = block.inputValue( self.colliderBoundingBoxMax) colliderBoundingBoxMaxVal = colliderBoundingBoxMaxHandle.asFloat3( ) #build new bounding box based on given values bbox = OpenMaya.MBoundingBox() bbox.expand( OpenMaya.MPoint(colliderBoundingBoxMinVal[0], colliderBoundingBoxMinVal[1], colliderBoundingBoxMinVal[2])) bbox.expand( OpenMaya.MPoint(colliderBoundingBoxMaxVal[0], colliderBoundingBoxMaxVal[1], colliderBoundingBoxMaxVal[2])) #set up point on mesh and intersector for returning closest point and accelParams if required pointOnMesh = OpenMaya.MPointOnMesh() self.intersector.create(inColliderMesh, colliderMatrixVal) #set up constants for allIntersections faceIds = None triIds = None idsSorted = False space = OpenMaya.MSpace.kWorld maxParam = 100000 testBothDirs = False accelParams = None sortHits = False hitRayParams = None hitFaces = None hitTriangles = None hitBary1 = None hitBary2 = None tolerance = 0.0001 floatVec = OpenMaya.MFloatVector( 0, 1, 0 ) #set up arbitrary vector n.b this is fine for what we want here but anything more complex may require vector obtained from vertex #deal with main mesh inMeshFn = OpenMaya.MFnMesh(inMesh) inPointArray = OpenMaya.MPointArray() inMeshFn.getPoints(inPointArray, OpenMaya.MSpace.kWorld) #create array to store final points and set to correct length length = inPointArray.length() finalPositionArray = OpenMaya.MPointArray() finalPositionArray.setLength(length) #loop through all points. could also be done with geoItr for num in range(length): point = inPointArray[num] #if point is within collider bounding box then consider it if bbox.contains(point): ##-- allIntersections variables --## floatPoint = OpenMaya.MFloatPoint(point) hitPoints = OpenMaya.MFloatPointArray() inColliderFn.allIntersections( floatPoint, floatVec, faceIds, triIds, idsSorted, space, maxParam, testBothDirs, accelParams, sortHits, hitPoints, hitRayParams, hitFaces, hitTriangles, hitBary1, hitBary2, tolerance) if hitPoints.length() % 2 == 1: #work out closest point closestPoint = OpenMaya.MPoint() inColliderFn.getClosestPoint( point, closestPoint, OpenMaya.MSpace.kWorld, None) #calculate delta and add to array delta = point - closestPoint finalPositionArray.set(point - delta, num) else: finalPositionArray.set(point, num) #if point is not in bounding box simply add the position to the final array else: finalPositionArray.set(point, num) inMeshFn.setPoints(finalPositionArray, OpenMaya.MSpace.kWorld)
def boundingBox(self): return OpenMaya.MBoundingBox(OpenMaya.MPoint(-1, -1, -1), OpenMaya.MPoint(1, 1, 1))