def getWeightsFromEnvelope(self, origin_dag_path, envelope_dag_path, attribute=None): print 'origin_dag_path\t', origin_dag_path if not isinstance(origin_dag_path, OpenMaya.MDagPath): origin_dag_path = self.getDagPath(origin_dag_path) if not isinstance(envelope_dag_path, OpenMaya.MDagPath): envelope_dag_path = self.getDagPath(envelope_dag_path) mfn_origin_mesh = OpenMaya.MFnMesh(origin_dag_path) origin_point_array = OpenMaya.MFloatPointArray() mfn_origin_mesh.getPoints(origin_point_array, OpenMaya.MSpace.kObject) if attribute: node, attribute = attribute.split('.') mplug = self.getPlug(node, attribute) mplug.setInt(mplug.asInt() + 1) mfn_envelope_mesh = OpenMaya.MFnMesh(envelope_dag_path) envelope_point_array = OpenMaya.MFloatPointArray() mfn_envelope_mesh.getPoints(envelope_point_array, OpenMaya.MSpace.kObject) if attribute: mplug.setInt(mplug.asInt() - 1) if envelope_point_array.length() != origin_point_array.length(): raise Exception('# Target does not match with base.') return weights = OpenMaya.MFloatArray() for index in range(origin_point_array.length()): origin_mvector = OpenMaya.MVector(origin_point_array[index]) envelope_mvector = OpenMaya.MVector(envelope_point_array[index]) length = origin_mvector - envelope_mvector weights.append(length.length()) return weights
def check_normal(objects): LOG_FORMAT = "%(asctime)s - %(levelname)s - %(message)s" logger = logging.getLogger("mylog") logger.setLevel(logging.ERROR) handle = logging.FileHandler('D:/mayaCheckNormal.log') formatter = logging.Formatter(LOG_FORMAT) handle.setFormatter(formatter) logger.addHandler(handle) if not objects: logger.error("{}:The scene lacks objects".format(mc.file(exn=1))) return for obj in objects: dag = pm.PyNode(obj).__apimdagpath__() it = OpenMaya.MItMeshPolygon(dag) temp = OpenMaya.MFnMesh(dag) ray_source = OpenMaya.MFloatPoint() hit_points = OpenMaya.MFloatPointArray() while not it.isDone(): center_point = it.center(OpenMaya.MSpace.kWorld) face_normal = OpenMaya.MVector() it.getNormal(face_normal, OpenMaya.MSpace.kWorld) d_normal = face_normal * 0.1 temp_point = center_point + d_normal ray_source.setCast(temp_point) b_intersection = temp.allIntersections( ray_source, OpenMaya.MFloatVector(face_normal), None, None, False, OpenMaya.MSpace.kWorld, 999, False, None, False, hit_points, None, None, None, None, None) if b_intersection and hit_points.length() % 2 != 0: logger.warning("%s.f[%d]" % (obj, it.index())) it.next()
def find_intersection_other(self, mesh1, mesh2): mesh1_dagPath = mesh1.__apimdagpath__() # mesh的节点路径 mesh2_dagPath = mesh2.__apimdagpath__() mesh1_itr = OpenMaya.MItMeshEdge(mesh1_dagPath) # MItMeshEdge 多边形边迭代器 mesh2_mesh = OpenMaya.MFnMesh(mesh2_dagPath) util = OpenMaya.MScriptUtil() # MScriptUtil 实用程序类,用于在Python中使用指针和引用 edge_len_ptr = util.asDoublePtr() # asDoublePtr() 返回指向此类数据的双指针。 edge_list = set() while not mesh1_itr.isDone(): mesh1_itr.getLength(edge_len_ptr) # getLength()返回当前边的长度。 edge_len = util.getDouble(edge_len_ptr) # getDouble() 获取Double型参数的值 start_pt = mesh1_itr.point(0, OpenMaya.MSpace.kWorld) # point()返回当前边的指定顶点的位置。 end_pt = mesh1_itr.point(1, OpenMaya.MSpace.kWorld) # MSpace 空间转换标识符 # kWorld 对象世界坐标系的数据 raySource = OpenMaya.MFloatPoint(start_pt) # MFloatPoint 以浮点类型来实现处理点 rayDirection = OpenMaya.MFloatVector(end_pt - start_pt) # MFloatVector 浮点数向量的向量类 faceIds = None triIds = None idsSorted = False # 不排序 space = OpenMaya.MSpace.kWorld maxParam = edge_len # 边长度、搜索半径 testBothDirections = False # accelParams = mesh2_mesh.autoUniformGridParams() # autoUniformGridParams创建一个MMeshIsectAccelParams配置对象 sortHits = False hitPoints = OpenMaya.MFloatPointArray() # MFloatPoint数据类型的矩阵 hitRayParams = None hitFaces = OpenMaya.MIntArray() # int数据类型矩阵 hitTriangles = None hitBary1s = None hitBary2s = None rayDirection.normalize() # 单位化 gotHit = mesh2_mesh.allIntersections( raySource, rayDirection, faceIds, triIds, idsSorted, space, maxParam, testBothDirections, accelParams, sortHits, hitPoints, hitRayParams, hitFaces, hitTriangles, hitBary1s, hitBary2s) # allIntersections 查找从raySource开始并与mesh在rayDirection中传播的射线的所有交点。 # 如果faceIds和triIds均为NULL,则将考虑网格中的所有三角形面片。 # 返回值True、False if gotHit: edge_list.add(mesh1_itr.index()) # 把边的序号存入edge_list mesh1_itr.next() # 获取碰撞的边再通过边转面 edge_list = ["%s.e[%s]" % (mesh1_dagPath.fullPathName(), edge_id) for edge_id in edge_list] facelist = pm.polyListComponentConversion(edge_list, fe=True, tf=True) # polyListComponentConversion 将多边形组件从一种或多种类型转换为另一种或多种类型 # fromEdge(fe)toFace(tf) # 展平序号 return pm.ls(facelist, flatten=True)
def sang_bs(mmddata, chue_nod_poly, khanat): print(u'blend shapeを作成中') list_chue_nod_bs = [ [], [], [], [] ] # ลิสต์เก็บชื่อโหนดเบลนด์เชปแต่ละหมวด (คิ้ว, ตา, ปาก, อื่นๆ) list_chue_bs_doem = [ [], [], [], [] ] # ลิสต์เก็บชื่อเดิม (ชื่อญี่ปุ่น) ของเบลนด์เชปแต่ละหมวด list_panel = [[], [], [], []] # ลิสต์เก็บเลขแสดงแผง เก็บไว้เผื่อใช้ตอนแปลงกลับ for i, mo in enumerate(mmddata.morphs): # สร้างเบลนด์เชปขึ้นมาเฉพาะกรณีที่เป็นมอร์ฟเลื่อนตำแหน่งจุด มอร์ฟแบบอื่นทำเป็นเบลนด์เชปไม่ได้ if (mo.morph_type == 1): # ชื่อเบลนด์เชปต้องแปลงเป็นอักษรโรมัน chue_bs = romaji(chuedidi(mo.name, u'bs%d' % i)) # ลอกโพลิกอนตัวเดิมมาเพื่อใช้ทำเบลนด์เชป chue_nod_poly_bs = mc.duplicate(chue_nod_poly, n=chue_bs)[0] sl = om.MSelectionList() sl.add(chue_nod_poly_bs) dagpath = om.MDagPath() sl.getDagPath(0, dagpath) fn_mesh = om.MFnMesh(dagpath) chut = om.MFloatPointArray() # สร้างอาเรย์เก็บตำแหน่งจุด fn_mesh.getPoints(chut) # ใส่ค่าตำแหน่งจุดให้อาเรย์ for off in mo.offsets: vi = off.vertex_index # ดัชนีของจุดที่เปลี่ยนตำแหน่ง d = off.position_offset # ค่าตำแหน่งที่เปลี่ยนไปของแต่ละจุด p = chut[vi] # ตำแหน่งเดิมของจุดบนโพลิกอน chut.set(vi, p.x + d.x * khanat, p.y + d.y * khanat, p.z - d.z * khanat) # แก้ค่าตำแหน่งจุด fn_mesh.setPoints( chut ) # นำค่าตำแหน่งจุดใหม่ที่ได้มาตั้งให้โพลิกอนสำหรับทำเบลนด์เชป list_chue_nod_bs[mo.panel - 1].append(chue_nod_poly_bs) list_chue_bs_doem[mo.panel - 1].append(chuedidi(mo.name, chue_bs)) list_panel[mo.panel - 1].append(mo.panel) else: print(u'~! morph ' + chuedidi(mo.name) + u'はblend shapeを作れません') # รวมเป็นลิสต์เดียวต่อเนื่องกัน เรียงตามหมวดหมู่ list_chue_nod_bs = list(itertools.chain(*list_chue_nod_bs)) it_chue_bs_doem = (u'%s๑%s๑%d' % (chue_nod_bs, chue_doem, panel) for chue_nod_bs, chue_doem, panel in zip(list_chue_nod_bs, itertools.chain( *list_chue_bs_doem), itertools.chain(*list_panel))) mc.select(list_chue_nod_bs, chue_nod_poly) # สร้างโหนดเบลนด์เชปขึ้นมา chue_nod_bs = mc.blendShape(n='bs_' + chue_nod_poly)[0] mc.delete( list_chue_nod_bs) # ลบโพลิกอนสำหรับทำเบลนด์เชปทิ้ง ไม่ต้องใช้แล้ว # บันทึกชื่อเดิมทั้งหมดของเบลนด์เชปเก็บไว้ เผื่อได้ใช้ mc.addAttr(chue_nod_bs, ln='namae', nn=u'名前', dt='string') mc.setAttr(chue_nod_bs + '.namae', u'๐'.join(it_chue_bs_doem), typ='string')
def pointInMesh(obj, point=(0.0, 0.0, 0.0), direction=(0.0, 0.0, 1.0)): obj_dag_path = OpenMaya.MDagPath.getAPathTo( pymel.core.PyNode(obj).__apimobject__()) obj_mfn_node = OpenMaya.MFnMesh(obj_dag_path) api_point = OpenMaya.MFloatPoint(*point) api_direction = OpenMaya.MFloatVector(*direction) farray = OpenMaya.MFloatPointArray() obj_mfn_node.allIntersections( api_point, api_direction, None, None, False, OpenMaya.MSpace.kWorld, 10000, False, None, # replace none with a mesh look up accelerator if needed False, farray, None, None, None, None, None) return farray.length() % 2 == 1
def initializeSelfVariables(self, dataBlock, envelope): # first and only MPlug attribut's declaration at first run (faster compute because variables are not re-created at each compute but only query) self.thisNode = self.thisMObject() # global command to make node paintable om.MGlobal.executeCommand( "makePaintable -attrType multiFloat -sm deformer jiggleDeformer weights;" ) self.envelopeHandle = dataBlock.inputValue( envelope ) # Some of the internal deformer node's attributs do not provide MPlug fonction self.lastPoints.copy( self.targetPoints ) # Variable init at first run with Target points coordinates velfloatTmp = om.MFloatPoint(0.0, 0.0, 0.0) self.lastVel = om.MFloatPointArray(self.targetPoints.length(), velfloatTmp) self.dampingRatio = dataBlock.inputValue(jiggleDeformer.dampingRatio) self.stiffness = om.MPlug(self.thisNode, jiggleDeformer.stiffness) self.weight = om.MPlug(self.thisNode, jiggleDeformer.weight) print "First init"
def rebuildMesh(self): ''' ''' # Start timer timer = cmds.timerX() # Rebuild Mesh Data meshData = om.MObject() meshUtil = om.MScriptUtil() numVertices = len(self._data['vertexList']) / 3 numPolygons = len(self._data['polyCounts']) polygonCounts = om.MIntArray() polygonConnects = om.MIntArray() meshUtil.createIntArrayFromList(self._data['polyCounts'], polygonCounts) meshUtil.createIntArrayFromList(self._data['polyConnects'], polygonConnects) # Rebuild UV Data uArray = om.MFloatArray() vArray = om.MFloatArray() meshUtil.createFloatArrayFromList(self._data['uArray'], uArray) meshUtil.createFloatArrayFromList(self._data['vArray'], vArray) uvCounts = om.MIntArray() uvIds = om.MIntArray() meshUtil.createIntArrayFromList(self._data['uvCounts'], uvCounts) meshUtil.createIntArrayFromList(self._data['uvIds'], uvIds) # Rebuild Vertex Array vertexArray = om.MFloatPointArray(numVertices, om.MFloatPoint.origin) vertexList = [ vertexArray.set(i, self._data['vertexList'][i * 3], self._data['vertexList'][i * 3 + 1], self._data['vertexList'][i * 3 + 2], 1.0) for i in xrange(numVertices) ] # Rebuild Mesh meshFn = om.MFnMesh() meshObj = meshFn.create(numVertices, numPolygons, vertexArray, polygonCounts, polygonConnects, uArray, vArray, meshData) # Assign UVs meshFn.assignUVs(uvCounts, uvIds) # Rename Mesh mesh = om.MFnDependencyNode(meshObj).setName(self._data['name'] + "WSMesh") meshShape = cmds.listRelatives(mesh, s=True, ni=True, pa=True)[0] # Assign Initial Shading Group cmds.sets(meshShape, fe='initialShadingGroup') # Print timer result buildTime = cmds.timerX(st=timer) print("MeshIntersectData: Geometry rebuild time for mesh {0}: {1}". format(mesh, str(buildTime))) return mesh
def buildRestABC(self, abcMesh, js): meshSchema = abcMesh.getSchema() rawFaces = meshSchema.getFaceIndicesProperty().samples[0] rawCounts = meshSchema.getFaceCountsProperty().samples[0] rawPos = meshSchema.getPositionsProperty().samples[0] name = js["systemName"] numVerts = len(rawPos) numFaces = len(rawCounts) counts = om.MIntArray() faces = om.MIntArray() ptr = 0 for i in rawCounts: counts.append(i) for j in reversed(rawFaces[ptr:ptr + i]): faces.append(j) ptr += i vertexArray = om.MFloatPointArray() for j in xrange(numVerts): fp = om.MFloatPoint(rawPos[j][0], rawPos[j][1], rawPos[j][2]) vertexArray.append(fp) meshFn = om.MFnMesh() meshMObj = meshFn.create(numVerts, numFaces, vertexArray, counts, faces) cName = "{0}_SIMPLEX".format(name) om.MFnDependencyNode(meshMObj).setName(cName) cmds.sets(cName, e=True, forceElement="initialShadingGroup") return cName
def polyTetrahedron( pointPositions=[[-1.0, 0.0, 0.0], [0.73444569110870361, 0.0, 1.0], [0.13706603646278381, 1.0, -0.0041212271898984909], [0.73444569110870361, 0.0, -1.0]]): numFaces = 4 numVertices = 4 faceCounts = OpenMaya.MIntArray() for i in [3, 3, 3, 3]: faceCounts.append(i) faceConnects = OpenMaya.MIntArray() for i in [0, 1, 2, 0, 2, 3, 0, 3, 1, 1, 3, 2]: faceConnects.append(i) points = OpenMaya.MFloatPointArray() for pointPosition in pointPositions: points.append(OpenMaya.MFloatPoint(*pointPosition)) meshFS = OpenMaya.MFnMesh() newMesh = meshFS.create(numVertices, numFaces, points, faceCounts, faceConnects, OpenMaya.MObject()) meshFS.updateSurface() nodeName = meshFS.name() cmds.sets(nodeName, e=True, fe='initialShadingGroup')
def get_uvNormal(surface=None, u=.5, v=.5): _str_func = 'get_normalAtPoint' selectionList = om.MSelectionList() #mPoint_source = om.MFloatPoint(point[0], point[1], point[2]) #Create an empty MFloatPoint to receive the hit point from the call. mPointArray_hits = om.MFloatPointArray() spc = om.MSpace.kWorld selectionList.add(surface) surfacePath = om.MDagPath() selectionList.getDagPath(0, surfacePath) surfaceFn = om.MFnNurbsSurface(surfacePath) #log.debug("Raw: {0} | {1}".format(uRaw,vRaw)) #__d = DIST.get_normalized_uv(mesh,uRaw,vRaw)#normalize data #l_rawUV.append([uRaw,vRaw]) #l_uv.append(__d['uv']) #....normal try: _res = surfaceFn.normal(u, v, om.MSpace.kWorld) return [_res.x, _res.y, _res.z] except Exception, err: log.warning(">>> {0} >> Failed to process normal: {1}".format( _str_func, err)) return [0, 0, 0]
def readRIPVertexes(f, count, vertDict): result = [] Vert_array = OpenMaya.MFloatPointArray() Normal_array = [] UArray = OpenMaya.MFloatArray() VArray = OpenMaya.MFloatArray() rawStructSize = len(vertDict) * 4 for i in range(count): vertexData = struct.unpack(vertDict, f.read(rawStructSize)) Vert_array.append(generateVertexFromData(vertexData)) Normal_array.append(generateNormalFromData(vertexData)) UArray.append(generateTexCoordFromData(vertexData, 0)) VArray.append(1 - generateTexCoordFromData(vertexData, 1)) # VertexData: # [0] - Vert_array # [1] - Normal_array # [2] - UArray # [3] - VArray result.append(Vert_array) result.append(Normal_array) result.append(UArray) result.append(VArray) return result
def allIntersections(mesh, source, direction, testBothDirections=False, maxDist=9999): ''' Return all intersection points on a specified mesh given a source point and direction @param mesh: Polygon mesh to perform intersection on @type mesh: str @param source: Source point for the intersection ray @type source: list or tuple or str @param direction: Direction of the intersection ray intersection @type direction: list or tuple @param testBothDirections: Test both directions for intersection @type testBothDirections: bool ''' # Get meshFn meshFn = getMeshFn(mesh) # Get source point sourcePt = OpenMaya.MFloatPoint(source[0], source[1], source[2]) # Get direction vector directionVec = OpenMaya.MFloatVector(direction[0], direction[1], direction[2]) # Calculate intersection hitPtArray = OpenMaya.MFloatPointArray() meshFn.allIntersections(sourcePt, directionVec, None, None, False, OpenMaya.MSpace.kWorld, maxDist, testBothDirections, None, True, hitPtArray, None, None, None, None, None, 0.0001) # Return intersection hit point return [(hitPtArray[i][0], hitPtArray[i][1], hitPtArray[i][2]) for i in range(hitPtArray.length())]
def test_if_inside_mesh(point, obj): dir=(0.0, 0.0, 1.0) sel = om.MSelectionList() dag = om.MDagPath() #replace torus with arbitrary shape name sel.add(obj) sel.getDagPath(0,dag) mesh = om.MFnMesh(dag) point = om.MFloatPoint(*point) dir = om.MFloatVector(*dir) farray = om.MFloatPointArray() mesh.allIntersections( point, dir, None, None, False, om.MSpace.kWorld, 10000, False, None, False, farray, None, None, None, None, None ) return farray.length()%2 == 1
def getClosestPointList(self,ptList): ''' ''' # Start timer timer = mc.timerX() # Display Progress glTools.utils.progressBar.init(status=('Building Closest Point Coord Array...'),maxValue=int(len(ptList)*0.1)) # Rebuild Mesh Data meshUtil = OpenMaya.MScriptUtil() numVertices = len(self._data['vertexList'])/3 numPolygons = len(self._data['polyCounts']) polygonCounts = OpenMaya.MIntArray() polygonConnects = OpenMaya.MIntArray() meshUtil.createIntArrayFromList(self._data['polyCounts'],polygonCounts) meshUtil.createIntArrayFromList(self._data['polyConnects'],polygonConnects) # Rebuild Vertex Array vertexArray = OpenMaya.MFloatPointArray(numVertices,OpenMaya.MFloatPoint.origin) vertexList = [vertexArray.set(i,self._data['vertexList'][i*3],self._data['vertexList'][i*3+1],self._data['vertexList'][i*3+2],1.0) for i in xrange(numVertices)] # Rebuild Mesh meshFn = OpenMaya.MFnMesh() meshData = OpenMaya.MFnMeshData().create() meshObj = meshFn.create(numVertices,numPolygons,vertexArray,polygonCounts,polygonConnects,meshData) # Build Mesh Intersector meshPt = OpenMaya.MPointOnMesh() meshIntersector = OpenMaya.MMeshIntersector() meshIntersector.create(meshObj,OpenMaya.MMatrix.identity) # Get Closest Point Data ptCount = len(ptList) pntList = [ (0,0,0) for i in range(ptCount) ] for i in range(ptCount): # Get Closest Point mpt = glTools.utils.base.getMPoint(ptList[i]) meshIntersector.getClosestPoint(mpt,meshPt,self.maxDist) # Get Mesh Point Data pt = meshPt.getPoint() pntList[i] = (pt[0],pt[1],pt[2]) # Update Progress Bar (Every 10th Iteration) if not i % 10: glTools.utils.progressBar.update(step=1) # ================= # - Return Result - # ================= # End Progress if showProgress: glTools.utils.progressBar.end() # Print timer result buildTime = mc.timerX(st=timer) print('MeshIntersectData: Closest Point search time for mesh "'+self._data['name']+'": '+str(buildTime)) return pntList
def buildMesh() : numVertices=4 numFaces=1 outputMesh = OpenMaya.MObject() points = OpenMaya.MFloatPointArray() faceConnects = OpenMaya.MIntArray() faceCounts = OpenMaya.MIntArray() p = OpenMaya.MFloatPoint(-1.0,0.0,-1.0) points.append(p) p = OpenMaya.MFloatPoint(-1.0,0.0,1.0) points.append(p) p = OpenMaya.MFloatPoint(1.0,0.0,1.0) points.append(p) p = OpenMaya.MFloatPoint(1.0,0.0,-1.0) points.append(p) faceConnects.append(0) faceConnects.append(1) faceConnects.append(2) faceConnects.append(3) faceCounts.append(4) meshFN = OpenMaya.MFnMesh() print ("create Mesh") meshFN.create(4, 1, points, faceCounts, faceConnects, outputMesh) nodeName = meshFN.name() print(nodeName) cmds.sets(nodeName, add='initialShadingGroup') cmds.select(nodeName) meshFN.updateSurface()
def createMesh(self, radius, outputMeshDataObj): self.vtx = [] self.createPoints(radius) num_verts = 12 num_faces = 20 edges_per_face = 3 pointArray = OpenMaya.MFloatPointArray() for i in range(0, num_verts): pointArray.append(self.vtx[i]) # can we skip this copy? nFaceConnects = num_faces * edges_per_face nEdges = nFaceConnects / 2 faceCounts = OpenMaya.MIntArray() for i in range(0, num_faces): faceCounts.append(edges_per_face) faceConnects = OpenMaya.MIntArray() for i in range(0, num_faces * edges_per_face): faceConnects.append(gons[i] - 1) outputMesh = OpenMaya.MFnMesh() newTransform = outputMesh.create( num_verts, num_faces, pointArray, \ faceCounts, faceConnects, \ outputMeshDataObj ) outputMesh.updateSurface()
def rebuild(self): ''' ''' # Start timer timer = mc.timerX() # Rebuild Mesh Data meshUtil = OpenMaya.MScriptUtil() numVertices = len(self._data['vertexList']) / 3 numPolygons = len(self._data['polyCounts']) polygonCounts = OpenMaya.MIntArray() polygonConnects = OpenMaya.MIntArray() meshUtil.createIntArrayFromList(self._data['polyCounts'], polygonCounts) meshUtil.createIntArrayFromList(self._data['polyConnects'], polygonConnects) # Rebuild UV Data uvCounts = OpenMaya.MIntArray() uvIds = OpenMaya.MIntArray() meshUtil.createIntArrayFromList(self._data['uvCounts'], uvCounts) meshUtil.createIntArrayFromList(self._data['uvIds'], uvIds) uArray = OpenMaya.MFloatArray() vArray = OpenMaya.MFloatArray() meshUtil.createFloatArrayFromList(self._data['uArray'], uArray) meshUtil.createFloatArrayFromList(self._data['vArray'], vArray) # Rebuild Vertex Array vertexArray = OpenMaya.MFloatPointArray(numVertices, OpenMaya.MFloatPoint.origin) vertexList = [ vertexArray.set(i, self._data['vertexList'][i * 3], self._data['vertexList'][i * 3 + 1], self._data['vertexList'][i * 3 + 2], 1.0) for i in xrange(numVertices) ] # Rebuild Mesh meshFn = OpenMaya.MFnMesh() meshData = OpenMaya.MFnMeshData().create() meshObj = meshFn.create(numVertices, numPolygons, vertexArray, polygonCounts, polygonConnects, uArray, vArray, meshData) # Assign UVs meshFn.assignUVs(uvCounts, uvIds) meshObjHandle = OpenMaya.MObjectHandle(meshObj) # Print Timed Result buildTime = mc.timerX(st=timer) print('MeshIntersectData: Data rebuild time for mesh "' + self._data['name'] + '": ' + str(buildTime)) # ================= # - Return Result - # ================= return meshObjHandle
def createShape_mesh(numVertices, numFaces, faceCounts, faceConnects, points, hardEdges, name=None, parent=None): """ Creates a mesh from the given parameters. These inputs are usually generated from the print_createShape_mesh function. """ if not parent: parentMObject = OpenMaya.MObject() else: if not ka_pymel.isPyTransform(parent): parent = pymel.PyNode(parent) parentMObject = parent.__apimobject__() if not name and parent: name = parent.nodeName() + 'Shape' faceCounts_MintArray = OpenMaya.MIntArray() for i in faceCounts: faceCounts_MintArray.append(i) faceConnects_MIntArray = OpenMaya.MIntArray() for i in faceConnects: faceConnects_MIntArray.append(i) points_MFloatPointArray = OpenMaya.MFloatPointArray() for point in points: points_MFloatPointArray.append(OpenMaya.MFloatPoint(*point)) meshFS = OpenMaya.MFnMesh() newMesh = meshFS.create(numVertices, numFaces, points_MFloatPointArray, faceCounts_MintArray, faceConnects_MIntArray, parentMObject) #for edge in hardEdges: #meshFS.setEdgeSmoothing(edge, False) meshFS.updateSurface() if name: mesh = cmds.rename(meshFS.name(), name) else: mesh = meshFS.name() hardEdgesStrings = [] for edge in hardEdges: hardEdgesStrings.append('%s.e[%s]' % (mesh, str(edge))) cmds.sets(mesh, e=True, fe='initialShadingGroup') cmds.polySoftEdge(*hardEdgesStrings, ch=0, a=0) return pymel.PyNode(mesh)
def searchArea(startPoint, endPoint, step, rayDirection, voxelCenterPositions): for point_Zcoord in floatRange(startPoint.z, endPoint.z, step): for point_Xcoord in floatRange(startPoint.x, endPoint.x, step): for point_Ycoord in floatRange(startPoint.y, endPoint.y, step): #create ray source and direction raySource = OpenMaya.MFloatPoint( point_Xcoord, point_Ycoord, point_Zcoord) #rayDirection = OpenMaya.MFloatVector(0,0,-1) hitPointArray = OpenMaya.MFloatPointArray() hitRayParams = OpenMaya.MFloatArray() tolerance = 1e-6 mMeshObj.allIntersections( raySource, #raySource rayDirection, #rayDirection None, #faceIds do not need to filter the face None, #triDis do not need to filter the tris False, # do not need to sort the IDs OpenMaya.MSpace. kTransform, #ray source and direction are specified in the mesh local coordinates float(9999), #the range of the ray False, #do not need to test both directions None, #do not need accelParams False, #do not need to sort hits hitPointArray, #return the hit point array hitRayParams, #return hit point distance params None, #do not need hit faces ids None, #do not need hit tris ids None, #do not need barycentric coordinates of faces None, #do not need barycentric coordinates of tris tolerance #hit tolerance ) #add the inside raysouce into list for voxel placement if (hitPointArray.length() % 2 == 1): voxelCenterPositions.append(raySource) #also need to query the intersection geometry color #find nearest intersection point #http://www.chadvernon.com/blog/resources/maya-api-programming/mscriptutil/ #Since the Maya API is designed as a C++ library, it has many pointers and references #that are passed into and returned from various functions. uvPoint = util.asFloat2Ptr() mPoint = OpenMaya.MPoint(raySource) mMeshObj.getUVAtPoint(mPoint, uvPoint) if self.skinCluster: pointWeight = self.getClosetPointWeight(mPoint) pointBlendWeight = self.getClosetPointBlendWeight( mPoint) voxelWeights.append(pointWeight) voxelBlendWeights.append(pointBlendWeight) u = util.getFloat2ArrayItem(uvPoint, 0, 0) v = util.getFloat2ArrayItem(uvPoint, 0, 1) uv = [u, v] uvArray.append(uv)
def __init__(self): self.vertAry = OpenMaya.MFloatPointArray() self.normAry = OpenMaya.MFloatVectorArray() self.uAry = OpenMaya.MFloatArray() self.vAry = OpenMaya.MFloatArray() self.vertIndex = OpenMaya.MIntArray() self.normIndex = OpenMaya.MIntArray() self.uvIndex = OpenMaya.MIntArray() self.matIndex = 0
def sampleShadingNetworkAtPoints(nodeAttr, points): numSamples = len(points) pointArray = points pointArray = OpenMaya.MFloatPointArray() pointArray.setLength(numSamples) refPoints = OpenMaya.MFloatPointArray() refPoints.setLength(numSamples) for i, point in enumerate(points): location = OpenMaya.MFloatPoint(point[0], point[1], point[2]) pointArray.set(location, i) refPoints.set(location, i) # but we don't need these useShadowMap = False reuseMaps = False cameraMatrix = OpenMaya.MFloatMatrix() uCoords = None vCoords = None normals = None tangentUs = None tangentVs = None filterSizes = None # and the return arguments are empty.... resultColors = OpenMaya.MFloatVectorArray() resultTransparencies = OpenMaya.MFloatVectorArray() # sample the node network OpenMayaRender.MRenderUtil.sampleShadingNetwork( nodeAttr, numSamples, useShadowMap, reuseMaps, cameraMatrix, pointArray, uCoords, vCoords, normals, refPoints, tangentUs, tangentVs, filterSizes, resultColors, resultTransparencies) # return formatted sampled colours return resultColors
def GETPOINTS_DB(geo): sel = om.MSelectionList() dag = om.MDagPath() sel.add(geo) sel.getDagPath(0,dag) mesh = om.MFnMesh(dag) vts=om.MFloatPointArray() mesh.getPoints(vts, om.MSpace.kWorld) return mesh,vts
def getWeightsFromCurve(self, curve_dag_path, geomerty_dag_path): if not isinstance(geomerty_dag_path, OpenMaya.MDagPath): geomerty_dag_path = self.getDagPath(geomerty_dag_path) if not isinstance(curve_dag_path, OpenMaya.MDagPath): curve_dag_path = self.getDagPath(curve_dag_path) weights = {} mfn_nurbs_curve = OpenMaya.MFnNurbsCurve(curve_dag_path) for cv in range(mfn_nurbs_curve.numCVs()): mfn_origin_mesh = OpenMaya.MFnMesh(geomerty_dag_path) origin_point_array = OpenMaya.MFloatPointArray() mfn_origin_mesh.getPoints(origin_point_array, OpenMaya.MSpace.kObject) position = OpenMaya.MPoint() mfn_nurbs_curve.getCV(cv, position) ing_position = OpenMaya.MPoint(position.x + 1, position.y, position.z) mfn_nurbs_curve.setCV(cv, ing_position) mfn_nurbs_curve.updateCurve() mfn_envelope_mesh = OpenMaya.MFnMesh(geomerty_dag_path) envelope_point_array = OpenMaya.MFloatPointArray() mfn_envelope_mesh.getPoints(envelope_point_array, OpenMaya.MSpace.kObject) mfn_nurbs_curve.setCV(cv, position) mfn_nurbs_curve.updateCurve() cv_weights = OpenMaya.MFloatArray() for index in range(origin_point_array.length()): origin_mvector = OpenMaya.MVector(origin_point_array[index]) envelope_mvector = OpenMaya.MVector( envelope_point_array[index]) length = origin_mvector - envelope_mvector cv_weights.append(length.length()) weight_data = {} weight_data['position'] = [position.x, position.y, position.z] weight_data['weights'] = cv_weights weights.setdefault(cv, weight_data) return weights
def create(verts, faces, merge=True): ''' Given a list of vertices (iterables of floats) and a list of faces (iterable of integer vert indices), creates and returns a maya Mesh ''' cmds.select(cl=True) outputMesh = OpenMaya.MObject() numFaces = len(faces) numVertices = len(verts) # point array of plane vertex local positions points = OpenMaya.MFloatPointArray() for eachVt in verts: p = OpenMaya.MFloatPoint(eachVt[0], eachVt[1], eachVt[2]) points.append(p) # vertex connections per poly face in one array of indexs into point array given above faceConnects = OpenMaya.MIntArray() for eachFace in faces: for eachCorner in eachFace: faceConnects.append(int(eachCorner)) # an array to hold the total number of vertices that each face has faceCounts = OpenMaya.MIntArray() for c in range(0, numFaces, 1): faceCounts.append(int(4)) # create mesh object using arrays above and get name of new mesh meshFN = OpenMaya.MFnMesh() """ print numVertices,numFaces print points print faceCounts print faceConnects """ newMesh = meshFN.create(numVertices, numFaces, points, faceCounts, faceConnects, outputMesh) nodeName = meshFN.name() cmds.sets(nodeName, add='initialShadingGroup') cmds.select(nodeName) meshFN.updateSurface() # this is useful because it deletes stray vertices (ie, those not used in any faces) if merge: cmds.polyMergeVertex(nodeName, ch=0) meshFN.updateSurface() return nodeName
def find_intersect_vertex(obj_A, obj_b): ''' ''' src_pml_node = pymel.core.PyNode(obj_A) dst_pml_node = pymel.core.PyNode(obj_b) src_dag_path = src_pml_node.__apiobject__() dst_dag_path = dst_pml_node.__apiobject__() src_mfn_node = OpenMaya.MFnMesh(src_dag_path) iterator = OpenMaya.MItGeometry(dst_dag_path) comp_list = list() closest_point = OpenMaya.MPoint() farray = OpenMaya.MFloatPointArray() point = OpenMaya.MFloatPoint() for i in xrange(iterator.count()): current_point = iterator.position(OpenMaya.MSpace.kWorld) src_mfn_node.getClosestPoint(current_point, closest_point, OpenMaya.MSpace.kWorld) point.setCast(current_point) vector = OpenMaya.MFloatVector(closest_point) farray.clear() src_mfn_node.allIntersections(point, vector, None, None, False, OpenMaya.MSpace.kWorld, 10000, False, None, False, farray, None, None, None, None, None) if farray.length() % 2 == 1: comp_list.append(iterator.index()) iterator.next() api_util = OpenMaya.MScriptUtil() api_util.createFromList(comp_list, len(comp_list)) int_ptr = api_util.asIntPtr() id_array = OpenMaya.MIntArray(int_ptr, len(comp_list)) single_components = OpenMaya.MFnSingleIndexedComponent() vertex_components = single_components.create( OpenMaya.MFn.kMeshVertComponent) single_components.addElements(id_array) mSelectionList = OpenMaya.MSelectionList() mSelectionList.add(dst_dag_path, vertex_components) OpenMaya.MGlobal.setActiveSelectionList(mSelectionList)
def returnCollisionPoints(point, dir, fnMesh): ''' Get collision information from a raycast onto a mesh - point: origin point in space of the ray - dir: direction of the ray - fnMesh: mesh used for the collision testing ''' point = om.MFloatPoint(*point) hitPoints = om.MFloatPointArray() hitFaces = om.MIntArray() fnMesh.allIntersections(point, dir, None, None, False, om.MSpace.kWorld, 10000, False, fnMesh.autoUniformGridParams(), False, hitPoints, None, hitFaces, None, None, None) return hitPoints, hitFaces
def get_polygon_mesh(self, m_dag_path): mfn_mesh = OpenMaya.MFnMesh(m_dag_path) point_array = OpenMaya.MFloatPointArray() mfn_mesh.getPoints(point_array, OpenMaya.MSpace.kObject) vertex_count = OpenMaya.MIntArray() vertex_array = OpenMaya.MIntArray() mfn_mesh.getVertices(vertex_count, vertex_array) set_names = [] mfn_mesh.getUVSetNames(set_names) uvs_data = {} for index in range(len(set_names)): u_array = OpenMaya.MFloatArray() v_array = OpenMaya.MFloatArray() mfn_mesh.getUVs(u_array, v_array, set_names[index]) uv_counts = OpenMaya.MIntArray() uv_ids = OpenMaya.MIntArray() mfn_mesh.getAssignedUVs(uv_counts, uv_ids, set_names[index]) current_set = {} current_set['set_name'] = set_names[index] current_set['u_array'] = list(u_array) current_set['v_array'] = list(v_array) current_set['uv_counts'] = list(uv_counts) current_set['uv_ids'] = list(uv_ids) uvs_data.setdefault(index, current_set) vertice_list = [] for index in range(point_array.length()): vertice_list.append((point_array[index].x, point_array[index].y, point_array[index].z, point_array[index].w)) parent_mobject = mfn_mesh.parent(0) parent_mfn_dag_node = OpenMaya.MFnDagNode(parent_mobject) data = {} data['name'] = { 'transform': parent_mfn_dag_node.name().encode(), 'shape': mfn_mesh.name().encode() } data['vertices'] = vertice_list data['vertex_count'] = list(vertex_count) data['vertex_list'] = list(vertex_array) data['uvs'] = uvs_data data['num_edges'] = mfn_mesh.numEdges() data['num_face_vertices'] = mfn_mesh.numFaceVertices() data['num_polygons'] = mfn_mesh.numPolygons() data['num_normals'] = mfn_mesh.numNormals() data['num_uv_sets'] = mfn_mesh.numUVSets() data['num_uvs'] = mfn_mesh.numUVs() data['num_vertices'] = mfn_mesh.numVertices() return data
def get_points(self): """ Storage for the vertex list for this mesh into point array. :Return: EX: [V3f(-11.8104429, 106.812759, -149.725311), V3f(-11.8439445, 106.808167, -149.66568), V3f(-11.8298216, 106.813248, -149.688171)] """ m_point_array = om.MFloatPointArray() self.mesh_fn.getPoints(m_point_array) points = list() for i in range(m_point_array.length()): point = m_point_array[i] points.append(V3f(point.x, point.y, point.z)) return points
def getIntersection(self, point, normal, mesh): """Get the "best" intersection to move point to on given mesh. Args: point (MFloatPoint): point to check if inside mesh. normal (MFloatVector): inverted normal of given point. mesh (MFnMesh): mesh to check if point inside. Returns: MPoint """ intersection_normal = OpenMaya.MVector() closest_point = OpenMaya.MPoint() # Get closest point/normal to given point in normal direction on mesh. mesh.getClosestPointAndNormal( OpenMaya.MPoint(point), closest_point, intersection_normal, OpenMaya.MSpace.kWorld, ) # if the the found normal on the mesh is in a direction opposite to the # given normal, fall back to given normal, else use the average normal. # This is to get a more even vertex distribution on the new mesh. angle = normal.angle(OpenMaya.MFloatVector(intersection_normal)) if angle >= math.pi or angle <= -math.pi: average_normal = normal else: average_normal = OpenMaya.MVector(normal) + intersection_normal # Find intersection in direction determined above. intersections = OpenMaya.MFloatPointArray() mesh.allIntersections(point, OpenMaya.MFloatVector(average_normal), None, None, False, OpenMaya.MSpace.kWorld, 1000, False, None, True, intersections, None, None, None, None, None) # If number of intersections is even then the given point is not inside # the mesh. The intersections are ordered so return the first one found # as that is the closest one. intersecting_point = None if intersections.length() % 2 == 1: intersecting_point = intersections[0] return intersecting_point
def rayIntersect(mesh, point, direction): hitPoints = None try: cmds.select(cl=True) om.MGlobal.selectByName(mesh) sList = om.MSelectionList() om.MGlobal.getActiveSelectionList(sList) item = om.MDagPath() sList.getDagPath(0, item) item.extendToShape() fnMesh = om.MFnMesh(item) raySource = om.MFloatPoint(point[0], point[1], point[2], 1.0) rayDir = om.MFloatVector(direction[0], direction[1], direction[2]) faceIds = None triIds = None idsSorted = False testBothDirections = False worldSpace = om.MSpace.kWorld maxParam = 999999 accelParams = None sortHits = True hitPoints = om.MFloatPointArray() hitRayParams = om.MFloatArray() hitFaces = om.MIntArray() hitTris = None hitBarys1 = None hitBarys2 = None tolerance = 0.0001 hit = fnMesh.allIntersections(raySource, rayDir, faceIds, triIds, idsSorted, worldSpace, maxParam, testBothDirections, accelParams, sortHits, hitPoints, hitRayParams, hitFaces, hitTris, hitBarys1, hitBarys2, tolerance) om.MGlobal.clearSelectionList() except: cmds.warning('Ray Intersection exception: ' + mesh) return hitPoints