public void receiveCurveFromMaya(string node_name, out Point3DCollection controlVertices, out List<double> weights, out List<double> knots, out int degree, out bool closed, out bool rational) { MPlug plLocal = getPlug(node_name, "local"); MObject oLocal = new MObject(); plLocal.getValue(oLocal); MFnNurbsCurve nc = new MFnNurbsCurve(oLocal); MPointArray p_aCVs = new MPointArray(); nc.getCVs(p_aCVs, MSpace.Space.kWorld); controlVertices = new Point3DCollection(); weights = new List<double>(); foreach (MPoint p in p_aCVs) { controlVertices.Add(new Point3D(p.x, p.y, p.z)); weights.Add(1.0); } double min = 0, max = 0; nc.getKnotDomain(ref min, ref max); MDoubleArray d_aKnots = new MDoubleArray(); nc.getKnots(d_aKnots); knots = new List<double>(); knots.Add(min); foreach (double d in d_aKnots) { knots.Add(d); } knots.Add(max); degree = nc.degree; closed = nc.form == MFnNurbsCurve.Form.kClosed ? true : false; rational = true; }
public static List <List <Point> > getFaceVerticies(MFnMesh mayaMesh) { List <List <Point> > faces = new List <List <Point> >(mayaMesh.numVertices); PointList verts; MPointArray mayaVerts = new MPointArray(); MIntArray ids = new MIntArray(); mayaMesh.getPoints(mayaVerts, MSpace.Space.kWorld); for (int i = 0; i < mayaMesh.numPolygons; i++) { mayaMesh.getPolygonVertices(i, ids); verts = new PointList(ids.Count); foreach (var vtxid in ids) { if (MGlobal.isZAxisUp) { verts.Add(Point.ByCoordinates(mayaVerts[vtxid].x, mayaVerts[vtxid].y, mayaVerts[vtxid].z)); } else { verts.Add(Point.ByCoordinates(mayaVerts[vtxid].x, -mayaVerts[vtxid].z, mayaVerts[vtxid].y)); } } faces.Add(verts); } return(faces); }
public static Point[][] GetSurfaceCVs(MFnNurbsSurface mayaSurface) { MPointArray cvs = new MPointArray(); mayaSurface.getCVs(cvs, MSpace.Space.kWorld); int cvUct = mayaSurface.numCVsInU; int cvVct = mayaSurface.numCVsInV; //setup the points Point[][] ctrlPts = new Point[cvUct][]; for (int i = 0; i < cvUct; i++) { ctrlPts[i] = new Point[cvVct]; for (int j = 0; j < cvVct; j++) { if (MGlobal.isZAxisUp) { ctrlPts[i][j] = Point.ByCoordinates(cvs[(i * cvVct) + j].x, cvs[(i * cvVct) + j].y, cvs[(i * cvVct) + j].z); } else { ctrlPts[i][j] = Point.ByCoordinates(cvs[(i * cvVct) + j].x, -cvs[(i * cvVct) + j].z, cvs[(i * cvVct) + j].y); } } } return(ctrlPts); }
public static MDagPath CreateCurve(MVector[] positions, string curveName, int degree = 1, MFnNurbsCurve.Form form = MFnNurbsCurve.Form.kOpen) { MPointArray points = new MPointArray(); for (int i = 0; i < positions.Length; i++) { points.Add(new MPoint(positions[i])); } return(CreateCurve(points, curveName, degree, form)); //string cmdStr = "cmds.curve(n='" + curveName + "',d=1,p=["; //for (int i = 0; i < ptCount; i++) //{ // if (i != 0) // { // cmdStr += ","; // } // cmdStr += ToCMDSParamStr(points[i]); //} //int[] indices = new int[ptCount]; //for (int i = 0; i < ptCount; i++) //{ // indices[i] = i; //} //cmdStr += "],k=[" + ToCMDSParamStr(indices, ptCount) + "])"; //Debug.Log(cmdStr); //string resultName = MGlobal.executePythonCommandStringResult(cmdStr); //return GetDagPathByName(resultName); }
public apiMeshGeom() { vertices = new MPointArray(); face_counts = new MIntArray(); face_connects = new MIntArray(); normals = new MVectorArray(); uvcoords = new apiMeshGeomUV(); faceCount = 0; }
public static MDagPath CreateCTL_Square(string ctlName = "square", float up = 0.5f, float down = -0.5f, float left = -0.5f, float right = 0.5f) { MPointArray points = new MPointArray(); points.Add(new MPoint(left, up, 0)); points.Add(new MPoint(left, down, 0)); points.Add(new MPoint(right, down, 0)); points.Add(new MPoint(right, up, 0)); points.Add(new MPoint(left, up, 0)); return(CreateCurve(points, ctlName, 1, MFnNurbsCurve.Form.kClosed)); }
internal static Surface mNurbsSurfaceToDynamoSurface(MFnNurbsSurface surface, MSpace.Space space) { MPointArray cvs = new MPointArray(); surface.getCVs(cvs, space); MDoubleArray knotU = new MDoubleArray(); MDoubleArray knotV = new MDoubleArray(); surface.getKnotsInU(knotU); surface.getKnotsInV(knotV); double Us = knotU[0], Ue = knotU[knotU.Count - 1], Vs = knotV[0], Ve = knotV[knotV.Count - 1]; //surface.getKnotDomain(ref Us, ref Ue, ref Vs, ref Ve); knotU.insert(Us, 0); knotU.Add(Ue); knotV.insert(Vs, 0); knotV.Add(Ve); int cvUct = surface.numCVsInU; int cvVct = surface.numCVsInV; int uDeg = surface.degreeU; int vDeg = surface.degreeV; Point[][] ctrlPts = new Point[cvUct][]; double[][] weights = new double[cvUct][]; for (int i = 0; i < cvUct; i++) { ctrlPts[i] = new Point[cvVct]; weights[i] = new double[cvVct]; for (int j = 0; j < cvVct; j++) { weights[i][j] = 1; if (MGlobal.isZAxisUp) { ctrlPts[i][j] = Point.ByCoordinates(cvs[(i * cvVct) + j].x, cvs[(i * cvVct) + j].y, cvs[(i * cvVct) + j].z); } else { ctrlPts[i][j] = Point.ByCoordinates(cvs[(i * cvVct) + j].x, -cvs[(i * cvVct) + j].z, cvs[(i * cvVct) + j].y); } } } //Surface result = NurbsSurface.ByControlPoints(ctrlPts, uDeg, vDeg); Surface result = NurbsSurface.ByControlPointsWeightsKnots(ctrlPts, weights, knotU.ToArray(), knotV.ToArray(), uDeg, vDeg); return(result); }
public void sendCurveToMaya(string node_name, Point3DCollection controlVertices, List <double> knots, int degree, MFnNurbsCurveForm form) { var dn = new MFnDagNode(getDagNode(node_name)); var plCreate = dn.findPlug("create"); var plDynamoCreate = new MPlug(); try { plDynamoCreate = dn.findPlug("dynamoCreate"); } catch { var tAttr = new MFnTypedAttribute(); var ldaDynamoCreate = tAttr.create("dynamoCreate", "dc", MFnData.Type.kNurbsCurve, MObject.kNullObj); try { dn.addAttribute(ldaDynamoCreate, MFnDependencyNode.MAttrClass.kLocalDynamicAttr); plDynamoCreate = dn.findPlug(ldaDynamoCreate); var dagm = new MDagModifier(); dagm.connect(plDynamoCreate, plCreate); dagm.doIt(); } catch { return; } } var ncd = new MFnNurbsCurveData(); var oOwner = ncd.create(); var nc = new MFnNurbsCurve(); var p_aControlVertices = new MPointArray(); foreach (var p in controlVertices) { p_aControlVertices.Add(new MPoint(p.X, p.Y, p.Z)); } var d_aKnots = new MDoubleArray(); for (var i = 1; i < knots.Count - 1; ++i) { d_aKnots.Add(knots[i]); } nc.create(p_aControlVertices, d_aKnots, (uint)degree, (MFnNurbsCurve.Form)form, false, true, oOwner); plDynamoCreate.setMObject(oOwner); MGlobal.executeCommandOnIdle(string.Format("dgdirty {0}.create;", node_name)); }
// Main selection routine // public override bool select(MSelectInfo selectInfo, MSelectionList selectionList, MPointArray worldSpaceSelectPts) // // Description: // // Main selection routine // // Arguments: // // selectInfo - the selection state information // selectionList - the list of selected items to add to // worldSpaceSelectPts - // { bool selected = false; bool componentSelected = false; bool hilited = false; hilited = (selectInfo.displayStatus == M3dView.DisplayStatus.kHilite); if (hilited) { componentSelected = selectVertices(selectInfo, selectionList, worldSpaceSelectPts); selected = selected || componentSelected; } if (!selected) { apiMesh meshNode = (apiMesh)surfaceShape; // NOTE: If the geometry has an intersect routine it should // be called here with the selection ray to determine if the // the object was selected. selected = true; MSelectionMask priorityMask = new MSelectionMask(MSelectionMask.SelectionType.kSelectNurbsSurfaces); MSelectionList item = new MSelectionList(); item.add(selectInfo.selectPath); MPoint xformedPt = new MPoint(); if (selectInfo.singleSelection) { MPoint center = meshNode.boundingBox().center; xformedPt = center; xformedPt.multiplyEqual(selectInfo.selectPath.inclusiveMatrix); } selectInfo.addSelection(item, xformedPt, selectionList, worldSpaceSelectPts, priorityMask, false); } return(selected); }
public TriangleMeshAdapater(MFnMesh mesh) { MIntArray indices = new MIntArray(); MIntArray triangleCounts = new MIntArray(); MPointArray points = new MPointArray(); mesh.getTriangles(triangleCounts, indices); mesh.getPoints(points); // Get the triangle indices Indices = new Int32Collection((int)indices.length); for (int i = 0; i < indices.length; ++i) { Indices.Add(indices[i]); } // Get the control points (vertices) Points = new Point3DCollection((int)points.length); for (int i = 0; i < (int)points.length; ++i) { MPoint pt = points[i]; Points.Add(new Point3D(pt.x, pt.y, pt.z)); } // Get the number of triangle faces and polygon faces Debug.Assert(indices.length % 3 == 0); int triFaces = (int)indices.length / 3; int polyFaces = mesh.numPolygons; // We have normals per polygon, we want one per triangle. Normals = new Vector3DCollection(triFaces); int nCurrentTriangle = 0; // Iterate over each polygon for (int i = 0; i < polyFaces; ++i) { // Get the polygon normal var maya_normal = new MVector(); mesh.getPolygonNormal((int)i, maya_normal); System.Windows.Media.Media3D.Vector3D normal = new System.Windows.Media.Media3D.Vector3D(maya_normal.x, maya_normal.y, maya_normal.z); // Iterate over each tri in the current polygon int nTrisAtFace = triangleCounts[i]; for (int j = 0; j < nTrisAtFace; ++j) { Debug.Assert(nCurrentTriangle < triFaces); Normals.Add(normal); nCurrentTriangle++; } } Debug.Assert(nCurrentTriangle == triFaces); }
public static MDagPath CreateCTL_Square(string ctlName = "square", float height = 1, float width = 1) { MPointArray points = new MPointArray(); float up = height / 2; float left = width / 2; points.Add(new MPoint(left, up, 0)); points.Add(new MPoint(left, -up, 0)); points.Add(new MPoint(-left, -up, 0)); points.Add(new MPoint(-left, up, 0)); points.Add(new MPoint(left, up, 0)); return(CreateCurve(points, ctlName, 1, MFnNurbsCurve.Form.kClosed)); }
public TriangleMeshAdapater(MFnMesh mesh) { MIntArray indices = new MIntArray(); MIntArray triangleCounts = new MIntArray(); MPointArray points = new MPointArray(); mesh.getTriangles(triangleCounts, indices); mesh.getPoints(points); // Get the triangle indices Indices = new Int32Collection((int)indices.length); for (int i = 0; i < indices.length; ++i) Indices.Add(indices[i]); // Get the control points (vertices) Points = new Point3DCollection((int)points.length); for (int i = 0; i < (int)points.length; ++i) { MPoint pt = points[i]; Points.Add(new Point3D(pt.x, pt.y, pt.z)); } // Get the number of triangle faces and polygon faces Debug.Assert(indices.length % 3 == 0); int triFaces = (int)indices.length / 3; int polyFaces = mesh.numPolygons; // We have normals per polygon, we want one per triangle. Normals = new Vector3DCollection(triFaces); int nCurrentTriangle = 0; // Iterate over each polygon for (int i = 0; i < polyFaces; ++i) { // Get the polygon normal var maya_normal = new MVector(); mesh.getPolygonNormal((int)i, maya_normal); System.Windows.Media.Media3D.Vector3D normal = new System.Windows.Media.Media3D.Vector3D(maya_normal.x, maya_normal.y, maya_normal.z); // Iterate over each tri in the current polygon int nTrisAtFace = triangleCounts[i]; for (int j = 0; j < nTrisAtFace; ++j) { Debug.Assert(nCurrentTriangle < triFaces); Normals.Add(normal); nCurrentTriangle++; } } Debug.Assert(nCurrentTriangle == triFaces); }
internal static Mesh MTDMeshFromMayaMesh(MFnMesh mayaMesh, MSpace.Space space) { PointList vertices = new PointList(mayaMesh.numVertices); ; List <IndexGroup> faceIndexList = new List <IndexGroup>(mayaMesh.numPolygons); MPointArray mayaVerts = new MPointArray(); mayaMesh.getPoints(mayaVerts, space); if (MGlobal.isYAxisUp) { vertices.AddRange(mayaVerts.Select(v => Point.ByCoordinates(v.x, -v.z, v.y))); } else { vertices.AddRange(mayaVerts.Select(v => Point.ByCoordinates(v.x, v.y, v.z))); } MIntArray faceIndex = new MIntArray(); for (int i = 0; i < mayaMesh.numPolygons; i++) { mayaMesh.getPolygonVertices(i, faceIndex); if (faceIndex.length > 4) { WarningException wa = new WarningException("The DynMesh will not show in Dynamo if it has any faces with 4 verts or more. The DynMesh can be represented as closed curves ."); return(null); } if (faceIndex.length == 3) { faceIndexList.Add(IndexGroup.ByIndices((uint)faceIndex[0], (uint)faceIndex[1], (uint)faceIndex[2])); } else { faceIndexList.Add(IndexGroup.ByIndices((uint)faceIndex[0], (uint)faceIndex[1], (uint)faceIndex[2], (uint)faceIndex[3])); } } mayaMesh.Dispose(); mayaVerts.Dispose(); faceIndex.Dispose(); using (vertices) { return(Mesh.ByPointsFaceIndices(vertices, faceIndexList)); } }
public Point3DCollection receiveVertexPositionsFromMaya(string node_name) { MPlug plLocal = getPlug(node_name, "outMesh"); MObject oOutMesh = new MObject(); plLocal.getValue(oOutMesh); MFnMesh m = new MFnMesh(oOutMesh); MPointArray p_aVertices = new MPointArray(); m.getPoints(p_aVertices, MSpace.Space.kWorld); Point3DCollection vertices = new Point3DCollection(); foreach (MPoint p in p_aVertices) { vertices.Add(new Point3D(p.x, p.y, p.z)); } return vertices; }
// Main selection routine // public override bool select(MSelectInfo selectInfo, MSelectionList selectionList, MPointArray worldSpaceSelectPts) { bool selected = false; bool componentSelected = false; bool hilited = false; apiSimpleShape shapeNode = surfaceShape as apiSimpleShape; if (shapeNode == null) { return(false); } hilited = (selectInfo.displayStatus == M3dView.DisplayStatus.kHilite); if (hilited) { componentSelected = selectVertices(selectInfo, selectionList, worldSpaceSelectPts); selected = selected || componentSelected; } if (!selected) { // NOTE: If the geometry has an intersect routine it should // be called here with the selection ray to determine if the // the object was selected. selected = true; MSelectionMask priorityMask = new MSelectionMask(MSelectionMask.SelectionType.kSelectNurbsSurfaces); MSelectionList item = new MSelectionList(); item.add(selectInfo.selectPath); MPoint xformedPt; if (selectInfo.singleSelection) { MPoint center = shapeNode.boundingBox().center; xformedPt = center.multiply(selectInfo.selectPath.inclusiveMatrix); } else { xformedPt = new MPoint(); } selectInfo.addSelection(item, xformedPt, selectionList, worldSpaceSelectPts, priorityMask, false); } return(selected); }
public static MDagPath CreateCurve(MPointArray points, string curveName, int degree = 1, MFnNurbsCurve.Form form = MFnNurbsCurve.Form.kOpen) { MDoubleArray indices = new MDoubleArray(); for (int i = 0; i < points.Count; i++) { indices.Add(i); } MFnNurbsCurve nc = new MFnNurbsCurve(); MObject curveObject = nc.create(points, indices, (uint)degree, form, false, false); MDagPath curveDagPath = MDagPath.getAPathTo(curveObject); MFnDependencyNode dn = new MFnDependencyNode(curveObject); dn.setName(curveName); return(curveDagPath); }
/* override */ public override bool select(MSelectInfo selectInfo, MSelectionList selectionList, MPointArray worldSpaceSelectPts) // // Select function. Gets called when the bbox for the object is selected. // This function just selects the object without doing any intersection tests. // { MSelectionMask priorityMask = new MSelectionMask(MSelectionMask.SelectionType.kSelectObjectsMask); MSelectionList item = new MSelectionList(); item.add(selectInfo.selectPath); MPoint xformedPt = new MPoint(); selectInfo.addSelection(item, xformedPt, selectionList, worldSpaceSelectPts, priorityMask, false); return(true); }
public Point3DCollection receiveVertexPositionsFromMaya(string node_name) { var plLocal = getPlug(node_name, "outMesh"); var oOutMesh = new MObject(); plLocal.getValue(oOutMesh); var m = new MFnMesh(oOutMesh); var p_aVertices = new MPointArray(); m.getPoints(p_aVertices, MSpace.Space.kWorld); var vertices = new Point3DCollection(); foreach (var p in p_aVertices) { vertices.Add(new Point3D(p.x, p.y, p.z)); } return(vertices); }
override public void deform(MDataBlock block, MItGeometry iter, MMatrix m, uint multiIndex) { MDataHandle angleData = block.inputValue(angle); MDataHandle envData = block.inputValue(envelope); double magnitude = angleData.asDouble; float env = envData.asFloat; var startTime = DateTime.Now; var poses = new MPointArray(); iter.allPositions(poses); //var newPos = VulankCompute.ComputeData(poses, (float)magnitude, env); VulankCompute.ComputeData(poses, (float)magnitude, env); iter.setAllPositions(poses); var timeSpand = DateTime.Now - startTime; MGlobal.displayInfo(string.Format("---------- total time : {0}", timeSpand.TotalSeconds)); //for (; !iter.isDone; iter.next()) //{ //MPoint pt = iter.position(); //// do the twist //// //double ff = magnitude * pt.y * env; //if (ff != 0.0) //{ // double cct = Math.Cos(ff); // double cst = Math.Sin(ff); // double tt = pt.x * cct - pt.z * cst; // pt.z = pt.x * cst + pt.z * cct; // pt.x = tt; ; //} //iter.setPosition(pt); //} }
public TriMesh ConvertTriMesh(MFnMesh mesh) { if (mesh == null) { MGlobal.displayInfo("Mesh is null \n"); } TriMesh trimesh = new TriMesh(); MIntArray indices = new MIntArray(); MIntArray triangleCounts = new MIntArray(); MPointArray points = new MPointArray(); mesh.getTriangles(triangleCounts, indices); mesh.getPoints(points); // Get the triangle indices for (int i = 0; i < (int)points.length; ++i) { MPoint pt = points[i]; VertexTraits trait = new VertexTraits(pt.x, pt.y, pt.z); trimesh.Vertices.Add(trait); } MGlobal.displayInfo(indices.Count.ToString() + "\n"); int j = 0; while (j < indices.Count) { int a = indices[j]; j++; int b = indices[j]; j++; int c = indices[j]; j++; trimesh.Faces.AddTriangles(trimesh.Vertices[a], trimesh.Vertices[b], trimesh.Vertices[c]); } return(trimesh); }
public static MDagPath CreateCTL_Crystal(string ctlName = "crystal") { MPointArray points = new MPointArray(); points.Add(new MPoint(0, 1, 0)); points.Add(new MPoint(0, 0, 1)); points.Add(new MPoint(1, 0, 0)); points.Add(new MPoint(0, -1, 0)); points.Add(new MPoint(0, 0, -1)); points.Add(new MPoint(1, 0, 0)); points.Add(new MPoint(0, 1, 0)); points.Add(new MPoint(0, 0, -1)); points.Add(new MPoint(-1, 0, 0)); points.Add(new MPoint(0, -1, 0)); points.Add(new MPoint(0, 0, 1)); points.Add(new MPoint(-1, 0, 0)); points.Add(new MPoint(0, 1, 0)); return(CreateCurve(points, ctlName, 1, MFnNurbsCurve.Form.kClosed)); }
public static List <Point> getMeshVerticies(MFnMesh mayaMesh) { PointList verts = new PointList(mayaMesh.numVertices); MPointArray mayaVerts = new MPointArray(); mayaMesh.getPoints(mayaVerts, MSpace.Space.kWorld); foreach (var v in mayaVerts) { if (MGlobal.isZAxisUp) { verts.Add(Point.ByCoordinates(v.x, v.y, v.z)); } else { verts.Add(Point.ByCoordinates(v.x, -v.z, v.y)); } } return(verts); }
public void receiveCurveFromMaya(string node_name, out Point3DCollection controlVertices, out List <double> weights, out List <double> knots, out int degree, out bool closed, out bool rational) { MPlug plLocal = getPlug(node_name, "local"); MObject oLocal = new MObject(); plLocal.getValue(oLocal); MFnNurbsCurve nc = new MFnNurbsCurve(oLocal); MPointArray p_aCVs = new MPointArray(); nc.getCVs(p_aCVs, MSpace.Space.kWorld); controlVertices = new Point3DCollection(); weights = new List <double>(); foreach (MPoint p in p_aCVs) { controlVertices.Add(new Point3D(p.x, p.y, p.z)); weights.Add(1.0); } double min = 0, max = 0; nc.getKnotDomain(ref min, ref max); MDoubleArray d_aKnots = new MDoubleArray(); nc.getKnots(d_aKnots); knots = new List <double>(); knots.Add(min); foreach (double d in d_aKnots) { knots.Add(d); } knots.Add(max); degree = nc.degree; closed = nc.form == MFnNurbsCurve.Form.kClosed ? true : false; rational = true; }
// // Description // // Create circles of vertices starting with // the top pole ending with the bottom pole // public void buildSphere(double rad, int div, MPointArray vertices, MIntArray counts, MIntArray connects, MVectorArray normals, apiMeshGeomUV uvs) { double u = -Math.PI / 2.0; double v = -Math.PI; double u_delta = Math.PI / ((double)div); double v_delta = 2 * Math.PI / ((double)div); MPoint topPole = new MPoint( 0.0, rad, 0.0 ); MPoint botPole = new MPoint( 0.0, -rad, 0.0 ); // Build the vertex and normal table // vertices.append( botPole ); normals.append( botPole.minus(MPoint.origin) ); int i; for ( i=0; i<(div-1); i++ ) { u += u_delta; v = -Math.PI; for ( int j=0; j<div; j++ ) { double x = rad * Math.Cos(u) * Math.Cos(v); double y = rad * Math.Sin(u); double z = rad * Math.Cos(u) * Math.Sin(v) ; MPoint pnt = new MPoint( x, y, z ); vertices.append( pnt ); normals.append( pnt.minus(MPoint.origin) ); v += v_delta; } } vertices.append( topPole ); normals.append( topPole.minus(MPoint.origin) ); // Create the connectivity lists // int vid = 1; int numV = 0; for ( i=0; i<div; i++ ) { for ( int j=0; j<div; j++ ) { if ( i==0 ) { counts.append( 3 ); connects.append( 0 ); connects.append( j+vid ); connects.append( (j==(div-1)) ? vid : j+vid+1 ); } else if ( i==(div-1) ) { counts.append( 3 ); connects.append( j+vid+1-div ); connects.append( vid+1 ); connects.append( j==(div-1) ? vid+1-div : j+vid+2-div ); } else { counts.append( 4 ); connects.append( j + vid+1-div ); connects.append( j + vid+1 ); connects.append( j == (div-1) ? vid+1 : j+vid+2 ); connects.append( j == (div-1) ? vid+1-div : j+vid+2-div ); } numV++; } vid = numV; } // TODO: Define UVs for sphere ... // }
public void sendCurveToMaya(string node_name, Point3DCollection controlVertices, List<double> knots, int degree, MFnNurbsCurveForm form) { MFnDagNode dn = new MFnDagNode(getDagNode(node_name)); MPlug plCreate = dn.findPlug("create"); MPlug plDynamoCreate = new MPlug(); try { plDynamoCreate = dn.findPlug("dynamoCreate"); } catch { MFnTypedAttribute tAttr = new MFnTypedAttribute(); MObject ldaDynamoCreate = tAttr.create("dynamoCreate", "dc", MFnData.Type.kNurbsCurve, MObject.kNullObj); try { dn.addAttribute(ldaDynamoCreate, MFnDependencyNode.MAttrClass.kLocalDynamicAttr); plDynamoCreate = dn.findPlug(ldaDynamoCreate); MDagModifier dagm = new MDagModifier(); dagm.connect(plDynamoCreate, plCreate); dagm.doIt(); } catch { return; } } MFnNurbsCurveData ncd = new MFnNurbsCurveData(); MObject oOwner = ncd.create(); MFnNurbsCurve nc = new MFnNurbsCurve(); MPointArray p_aControlVertices = new MPointArray(); foreach (Point3D p in controlVertices) { p_aControlVertices.Add(new MPoint(p.X, p.Y, p.Z)); } MDoubleArray d_aKnots = new MDoubleArray(); for (int i = 1; i < knots.Count - 1; ++i ) { d_aKnots.Add(knots[i]); } nc.create(p_aControlVertices, d_aKnots, (uint)degree, (MFnNurbsCurve.Form)form, false, true, oOwner); plDynamoCreate.setMObject(oOwner); MGlobal.executeCommandOnIdle(String.Format("dgdirty {0}.create;", node_name)); }
public void receiveCurveFromMaya(string nodeName, int space, out Point3DCollection controlVertices, out List <double> weights, out List <double> knots, out int degree, out bool closed, out bool rational) { var dagnode = getDagNode(nodeName); var nc = new MFnNurbsCurve(dagnode); var p_aCVs = new MPointArray(); switch (space) { case 0: //object nc.getCVs(p_aCVs, MSpace.Space.kObject); break; case 1: //world nc.getCVs(p_aCVs, MSpace.Space.kWorld); break; default: nc.getCVs(p_aCVs, MSpace.Space.kWorld); break; } controlVertices = new Point3DCollection(); weights = new List <double>(); if (MGlobal.isZAxisUp) { foreach (var p in p_aCVs) { controlVertices.Add(new Point3D(p.x, p.y, p.z)); weights.Add(1.0); } } else { foreach (var p in p_aCVs) { controlVertices.Add(new Point3D(p.x, -p.z, p.y)); weights.Add(1.0); } } double min = 0, max = 0; nc.getKnotDomain(ref min, ref max); var d_aKnots = new MDoubleArray(); nc.getKnots(d_aKnots); knots = new List <double>(); knots.Add(min); foreach (var d in d_aKnots) { knots.Add(d); } knots.Add(max); degree = nc.degree; closed = nc.form == MFnNurbsCurve.Form.kClosed ? true : false; rational = true; }
public bool selectVertices(MSelectInfo selectInfo, MSelectionList selectionList, MPointArray worldSpaceSelectPts) // // Description: // // Vertex selection. // // Arguments: // // selectInfo - the selection state information // selectionList - the list of selected items to add to // worldSpaceSelectPts - // { bool selected = false; M3dView view = selectInfo.view; MPoint xformedPoint = new MPoint(); MPoint selectionPoint = new MPoint(); double z = 0.0; double previousZ = 0.0; int closestPointVertexIndex = -1; MDagPath path = selectInfo.multiPath; // Create a component that will store the selected vertices // MFnSingleIndexedComponent fnComponent = new MFnSingleIndexedComponent(); MObject surfaceComponent = fnComponent.create(MFn.Type.kMeshVertComponent); uint vertexIndex; // if the user did a single mouse click and we find > 1 selection // we will use the alignmentMatrix to find out which is the closest // MMatrix alignmentMatrix = new MMatrix(); MPoint singlePoint = new MPoint(); bool singleSelection = selectInfo.singleSelection; if (singleSelection) { alignmentMatrix = selectInfo.alignmentMatrix; } // Get the geometry information // apiMesh meshNode = (apiMesh)surfaceShape; apiMeshGeom geom = meshNode.meshGeom(); // Loop through all vertices of the mesh and // see if they lie withing the selection area // uint numVertices = geom.vertices.length; for (vertexIndex = 0; vertexIndex < numVertices; vertexIndex++) { MPoint currentPoint = geom.vertices[(int)vertexIndex]; // Sets OpenGL's render mode to select and stores // selected items in a pick buffer // view.beginSelect(); OpenGL.glBegin(OpenGL.GL_POINTS); OpenGL.glVertex3f((float)currentPoint[0], (float)currentPoint[1], (float)currentPoint[2]); OpenGL.glEnd(); if (view.endSelect() > 0) // Hit count > 0 { selected = true; if (singleSelection) { xformedPoint = currentPoint; xformedPoint.homogenize(); xformedPoint.multiplyEqual(alignmentMatrix); z = xformedPoint.z; if (closestPointVertexIndex < 0 || z > previousZ) { closestPointVertexIndex = (int)vertexIndex; singlePoint = currentPoint; previousZ = z; } } else { // multiple selection, store all elements // fnComponent.addElement((int)vertexIndex); } } } // If single selection, insert the closest point into the array // if (selected && selectInfo.singleSelection) { fnComponent.addElement(closestPointVertexIndex); // need to get world space position for this vertex // selectionPoint = singlePoint; selectionPoint.multiplyEqual(path.inclusiveMatrix); } // Add the selected component to the selection list // if (selected) { MSelectionList selectionItem = new MSelectionList(); selectionItem.add(path, surfaceComponent); MSelectionMask mask = new MSelectionMask(MSelectionMask.SelectionType.kSelectComponentsMask); selectInfo.addSelection( selectionItem, selectionPoint, selectionList, worldSpaceSelectPts, mask, true); } return(selected); }
public static void ToMaya(Curve CurveToSend, string name) { NurbsCurve ctsAsNurb = null; if (CurveToSend is Rectangle) { Rectangle rec = (Rectangle)CurveToSend; ctsAsNurb = NurbsCurve.ByControlPoints(rec.Points, 1, true); } else if (CurveToSend is Polygon) { Polygon rec = (Polygon)CurveToSend; ctsAsNurb = NurbsCurve.ByControlPoints(rec.Points, 1, true); } else { ctsAsNurb = CurveToSend.ToNurbsCurve(); } var ncd = new MFnNurbsCurveData(); MFnNurbsCurveForm mfnform; if (ctsAsNurb.IsClosed) { mfnform = MFnNurbsCurveForm.kClosed; } else { mfnform = MFnNurbsCurveForm.kOpen; } var mayaCurve = new MFnNurbsCurve(); var vtxs = new MPointArray(); var cvs = ctsAsNurb.ControlPoints(); var yUp = MGlobal.isYAxisUp; if (yUp) { foreach (var cv in cvs) { var pt = new MPoint(cv.X, cv.Z, -cv.Y); vtxs.Add(pt); //pt.Dispose(); } } else { foreach (var cv in cvs) { var pt = new MPoint(cv.X, cv.Y, cv.Z); vtxs.Add(pt); //pt.Dispose(); } } var knots = ctsAsNurb.Knots(); var crvKnots = new MDoubleArray(knots); crvKnots.RemoveAt(0); crvKnots.RemoveAt(crvKnots.Count - 1); MDagPath node = null; var nodeExists = false; Task checkNode = null; Task deleteNode = null; try { node = DMInterop.getDagNode(name); nodeExists = true; } catch (Exception) { nodeExists = false; } MObject obj; if (nodeExists) { MDagPath nodeShape = node; nodeShape.extendToShape(); var modifyCrv = new MDGModifier(); mayaCurve = new MFnNurbsCurve(nodeShape); try { MFnNurbsCurveData dataCreator = new MFnNurbsCurveData(); MObject outCurveData = dataCreator.create(); var span = (vtxs.Count - ctsAsNurb.Degree); string rblCmd = $"rebuildCurve -rt 0 -s {span} -d {ctsAsNurb.Degree} {name}"; if (mayaCurve.numCVs != vtxs.Count || mayaCurve.degree != ctsAsNurb.Degree) { MGlobal.executeCommand(rblCmd); } mayaCurve.setCVs(vtxs); mayaCurve.setKnots(crvKnots, 0, crvKnots.length - 1); mayaCurve.updateCurve(); modifyCrv.doIt(); if (CurveToSend.GetType() == typeof(Circle)) { span = 8; rblCmd = $"rebuildCurve -rt 0 -s {span} {name}"; MGlobal.executeCommand(rblCmd); } } catch (Exception e) { MGlobal.displayWarning(e.Message); } } else { obj = mayaCurve.create(vtxs, crvKnots, (uint)ctsAsNurb.Degree, (MFnNurbsCurve.Form)mfnform, false, ctsAsNurb.IsRational); MFnDependencyNode nodeFn = new MFnDagNode(obj); nodeFn.setName(name); } }
/* override */ public override bool select(MSelectInfo selectInfo, MSelectionList selectionList, MPointArray worldSpaceSelectPts) // // Select function. Gets called when the bbox for the object is selected. // This function just selects the object without doing any intersection tests. // { MSelectionMask priorityMask = new MSelectionMask(MSelectionMask.SelectionType.kSelectObjectsMask); MSelectionList item = new MSelectionList(); item.add(selectInfo.selectPath); MPoint xformedPt = new MPoint(); selectInfo.addSelection(item, xformedPt, selectionList, worldSpaceSelectPts, priorityMask, false); return true; }
public void Create(SKLFile skl) { MSelectionList currentSelection = MGlobal.activeSelectionList; MItSelectionList currentSelectionIterator = new MItSelectionList(currentSelection, MFn.Type.kMesh); MDagPath meshDagPath = new MDagPath(); if (currentSelectionIterator.isDone) { MGlobal.displayError("SKNFile:Create - No mesh selected!"); throw new Exception("SKNFile:Create - No mesh selected!"); } else { currentSelectionIterator.getDagPath(meshDagPath); currentSelectionIterator.next(); if (!currentSelectionIterator.isDone) { MGlobal.displayError("SKNFile:Create - More than one mesh selected!"); throw new Exception("SKNFile:Create - More than one mesh selected!"); } } MFnMesh mesh = new MFnMesh(meshDagPath); //Find Skin Cluster MPlug inMeshPlug = mesh.findPlug("inMesh"); MPlugArray inMeshConnections = new MPlugArray(); inMeshPlug.connectedTo(inMeshConnections, true, false); if (inMeshConnections.length == 0) { MGlobal.displayError("SKNFile:Create - Failed to find Skin Cluster!"); throw new Exception("SKNFile:Create - Failed to find Skin Cluster!"); } MPlug outputGeometryPlug = inMeshConnections[0]; MFnSkinCluster skinCluster = new MFnSkinCluster(outputGeometryPlug.node); MDagPathArray influenceDagPaths = new MDagPathArray(); uint influenceCount = skinCluster.influenceObjects(influenceDagPaths); MGlobal.displayInfo("SKNFile:Create - Influence Count: " + influenceCount); //Get SKL Influence Indices MIntArray sklInfluenceIndices = new MIntArray(influenceCount); for (int i = 0; i < influenceCount; i++) { MDagPath jointDagPath = influenceDagPaths[i]; MGlobal.displayInfo(jointDagPath.fullPathName); //Loop through Joint DAG Paths, if we find a math for the influence, write the index for (int j = 0; j < skl.JointDagPaths.Count; j++) { if (jointDagPath.equalEqual(skl.JointDagPaths[j])) { MGlobal.displayInfo("Found coresponding DAG path"); sklInfluenceIndices[i] = j; break; } } } //Add Influence indices to SKL File MIntArray maskInfluenceIndex = new MIntArray(influenceCount); for (int i = 0; i < influenceCount; i++) { maskInfluenceIndex[i] = i; skl.Influences.Add((short)sklInfluenceIndices[i]); } MObjectArray shaders = new MObjectArray(); MIntArray polygonShaderIndices = new MIntArray(); mesh.getConnectedShaders(meshDagPath.isInstanced ? meshDagPath.instanceNumber : 0, shaders, polygonShaderIndices); uint shaderCount = shaders.length; if (shaderCount > 32) //iirc 32 is the limit of how many submeshes there can be for an SKN file { MGlobal.displayError("SKNFile:Create - You've exceeded the maximum limit of 32 shaders"); throw new Exception("SKNFile:Create - You've exceeded the maximum limit of 32 shaders"); } MIntArray vertexShaders = new MIntArray(); ValidateMeshTopology(mesh, meshDagPath, polygonShaderIndices, ref vertexShaders, shaderCount); //Get Weights MFnSingleIndexedComponent vertexIndexedComponent = new MFnSingleIndexedComponent(); MObject vertexComponent = vertexIndexedComponent.create(MFn.Type.kMeshVertComponent); MIntArray groupVertexIndices = new MIntArray((uint)mesh.numVertices); for (int i = 0; i < mesh.numVertices; i++) { groupVertexIndices[i] = i; } vertexIndexedComponent.addElements(groupVertexIndices); MDoubleArray weights = new MDoubleArray(); uint weightsInfluenceCount = 0; skinCluster.getWeights(meshDagPath, vertexComponent, weights, ref weightsInfluenceCount); //Check if vertices don't have more than 4 influences and normalize weights for (int i = 0; i < mesh.numVertices; i++) { int vertexInfluenceCount = 0; double weightSum = 0; for (int j = 0; j < weightsInfluenceCount; j++) { double weight = weights[(int)(i * weightsInfluenceCount) + j]; if (weight != 0) { vertexInfluenceCount++; weightSum += weight; } } if (vertexInfluenceCount > 4) { MGlobal.displayError("SKNFile:Create - Mesh contains a vertex with more than 4 influences"); throw new Exception("SKNFile:Create - Mesh contains a vertex with more than 4 influences"); } //Normalize weights for (int j = 0; j < weightsInfluenceCount; j++) { weights[(int)(i * influenceCount) + j] /= weightSum; } } List <MIntArray> shaderVertexIndices = new List <MIntArray>(); List <List <SKNVertex> > shaderVertices = new List <List <SKNVertex> >(); List <MIntArray> shaderIndices = new List <MIntArray>(); for (int i = 0; i < shaderCount; i++) { shaderVertexIndices.Add(new MIntArray()); shaderVertices.Add(new List <SKNVertex>()); shaderIndices.Add(new MIntArray()); } MItMeshVertex meshVertexIterator = new MItMeshVertex(meshDagPath); for (meshVertexIterator.reset(); !meshVertexIterator.isDone; meshVertexIterator.next()) { int index = meshVertexIterator.index(); int shader = vertexShaders[index]; if (shader == -1) { MGlobal.displayWarning("SKNFile:Create - Mesh contains a vertex with no shader"); continue; } MPoint pointPosition = meshVertexIterator.position(MSpace.Space.kWorld); Vector3 position = new Vector3((float)pointPosition.x, (float)pointPosition.y, (float)pointPosition.z); MVectorArray normals = new MVectorArray(); MIntArray uvIndices = new MIntArray(); Vector3 normal = new Vector3(); byte[] weightIndices = new byte[4]; float[] vertexWeights = new float[4]; meshVertexIterator.getNormals(normals); //Normalize normals for (int i = 0; i < normals.length; i++) { normal.X += (float)normals[i].x; normal.Y += (float)normals[i].y; normal.Z += (float)normals[i].z; } normal.X /= normals.length; normal.Y /= normals.length; normal.Z /= normals.length; //Get Weight Influences and Weights int weightsFound = 0; for (int j = 0; j < weightsInfluenceCount && weightsFound < 4; j++) { double weight = weights[(int)(index * weightsInfluenceCount) + j]; if (weight != 0) { weightIndices[weightsFound] = (byte)maskInfluenceIndex[j]; vertexWeights[weightsFound] = (float)weight; weightsFound++; } } //Get unique UVs meshVertexIterator.getUVIndices(uvIndices); if (uvIndices.length != 0) { List <int> seen = new List <int>(); for (int j = 0; j < uvIndices.length; j++) { int uvIndex = uvIndices[j]; if (!seen.Contains(uvIndex)) { seen.Add(uvIndex); float u = 0; float v = 0; mesh.getUV(uvIndex, ref u, ref v); SKNVertex vertex = new SKNVertex(position, weightIndices, vertexWeights, normal, new Vector2(u, 1 - v)); vertex.UVIndex = uvIndex; shaderVertices[shader].Add(vertex); shaderVertexIndices[shader].append(index); } } } else { MGlobal.displayError("SKNFile:Create - Mesh contains a vertex with no UVs"); throw new Exception("SKNFile:Create - Mesh contains a vertex with no UVs"); } } //Convert from Maya indices to data indices int currentIndex = 0; MIntArray dataIndices = new MIntArray((uint)mesh.numVertices, -1); for (int i = 0; i < shaderCount; i++) { for (int j = 0; j < shaderVertexIndices[i].length; j++) { int index = shaderVertexIndices[i][j]; if (dataIndices[index] == -1) { dataIndices[index] = currentIndex; shaderVertices[i][j].DataIndex = currentIndex; } else { shaderVertices[i][j].DataIndex = dataIndices[index]; } currentIndex++; } this.Vertices.AddRange(shaderVertices[i]); } MItMeshPolygon polygonIterator = new MItMeshPolygon(meshDagPath); for (polygonIterator.reset(); !polygonIterator.isDone; polygonIterator.next()) { int polygonIndex = (int)polygonIterator.index(); int shaderIndex = polygonShaderIndices[polygonIndex]; MIntArray indices = new MIntArray(); MPointArray points = new MPointArray(); polygonIterator.getTriangles(points, indices); if (polygonIterator.hasUVsProperty) { MIntArray vertices = new MIntArray(); MIntArray newIndices = new MIntArray(indices.length, -1); polygonIterator.getVertices(vertices); for (int i = 0; i < vertices.length; i++) { int dataIndex = dataIndices[vertices[i]]; int uvIndex; polygonIterator.getUVIndex(i, out uvIndex); if (dataIndex == -1 || dataIndex >= this.Vertices.Count) { MGlobal.displayError("SKNFIle:Create - Data Index outside of range"); throw new Exception("SKNFIle:Create - Data Index outside of range"); } for (int j = dataIndex; j < this.Vertices.Count; j++) { if (this.Vertices[j].DataIndex != dataIndex) { MGlobal.displayError("SKNFIle:Create - Can't find corresponding face vertex in data"); throw new Exception("SKNFIle:Create - Can't find corresponding face vertex in data"); } else if (this.Vertices[j].UVIndex == uvIndex) { for (int k = 0; k < indices.length; k++) { if (indices[k] == vertices[i]) { newIndices[k] = j; } } break; } } } for (int i = 0; i < newIndices.length; i++) { shaderIndices[shaderIndex].append(newIndices[i]); } } else { for (int i = 0; i < indices.length; i++) { shaderIndices[shaderIndex].append(dataIndices[indices[i]]); } } } uint startIndex = 0; uint startVertex = 0; for (int i = 0; i < shaderCount; i++) { MPlug shaderPlug = new MFnDependencyNode(shaders[i]).findPlug("surfaceShader"); MPlugArray plugArray = new MPlugArray(); shaderPlug.connectedTo(plugArray, true, false); string name = new MFnDependencyNode(plugArray[0].node).name; uint indexCount = shaderIndices[i].length; uint vertexCount = shaderVertexIndices[i].length; //Copy indices to SKLFile for (int j = 0; j < indexCount; j++) { this.Indices.Add((ushort)shaderIndices[i][j]); } this.Submeshes.Add(new SKNSubmesh(name, startVertex, vertexCount, startIndex, indexCount)); startIndex += indexCount; startVertex += vertexCount; } MGlobal.displayInfo("SKNFile:Create - Created SKN File"); }
public static void ToMaya(Surface SurfaceToSend, string name, string groupName) { NurbsSurface dynSurf; try { dynSurf = SurfaceToSend.ToNurbsSurface(); } catch (Exception) { dynSurf = null; MGlobal.displayWarning("Surface has no nurbSurface form"); } //MFnNurbsSurface updatedSurface; MPointArray cvs = new MPointArray(); Point[][] ctrlPts = dynSurf.ControlPoints(); for (int i = 0; i < ctrlPts.Length; i++) { for (int j = 0; j < ctrlPts[i].Length; j++) { MPoint p = new MPoint(); if (MGlobal.isZAxisUp) { p.x = ctrlPts[i][j].X; p.y = ctrlPts[i][j].Y; p.z = ctrlPts[i][j].Z; } else { p.x = ctrlPts[i][j].X; p.y = ctrlPts[i][j].Z; p.z = -ctrlPts[i][j].Y; } cvs.Add(p); } } MDoubleArray uknot = new MDoubleArray(dynSurf.UKnots()); uknot.RemoveAt(0); uknot.RemoveAt(uknot.Count - 1); MDoubleArray vknot = new MDoubleArray(dynSurf.VKnots()); vknot.RemoveAt(0); vknot.RemoveAt(vknot.Count - 1); MFnNurbsSurface.Form formU = MFnNurbsSurface.Form.kInvalid; MFnNurbsSurface.Form formV = MFnNurbsSurface.Form.kInvalid; if (dynSurf.IsPeriodicInU) { formU = MFnNurbsSurface.Form.kPeriodic; } else if (dynSurf.ClosedInU) { formU = MFnNurbsSurface.Form.kClosed; } else { formU = MFnNurbsSurface.Form.kOpen; } if (dynSurf.IsPeriodicInV) { formV = MFnNurbsSurface.Form.kPeriodic; } else if (dynSurf.ClosedInV) { formV = MFnNurbsSurface.Form.kClosed; } else { formV = MFnNurbsSurface.Form.kOpen; } MDagPath existingDagPath = null; bool nodeExists = false; //trims //toDo: impement trims Task checkNode = null; try { checkNode = Task.Factory.StartNew(() => existingDagPath = DMInterop.getDagNode(name)); checkNode.Wait(500); nodeExists = true; } catch (Exception) { nodeExists = false; } MObject obj; if (nodeExists) { if (checkNode.IsCompleted) { MFnNurbsSurface existingSurface = new MFnNurbsSurface(existingDagPath); MDGModifier mdgModifier = new MDGModifier(); // if (existingSurface.degreeU == dynSurf.DegreeU && existingSurface.degreeV== dynSurf.DegreeV && existingSurface.numCVsInU == ctrlPts.Length && existingSurface.numCVsInV == ctrlPts[0].Length ) //{ if (existingSurface.degreeU != dynSurf.DegreeU || existingSurface.degreeV != dynSurf.DegreeV || existingSurface.numCVsInU != ctrlPts.Length || existingSurface.numCVsInV != ctrlPts[0].Length) { //this is a hack to rebuild the surface. proper way is to make new surface and assign as input to aold surface MGlobal.executeCommand(string.Format("rebuildSurface -du {0} -dv {1} -su {2} -sv {3} {4}", dynSurf.DegreeU, dynSurf.DegreeV, ctrlPts.Length - 3, ctrlPts[0].Length - 3, name)); } // updatedSurface = existingSurface; existingSurface.setCVs(cvs); existingSurface.setKnotsInU(uknot, 0, (uint)existingSurface.numKnotsInU - 1); existingSurface.setKnotsInV(vknot, 0, (uint)existingSurface.numKnotsInV - 1); existingSurface.updateSurface(); // } /* * else * * { * //get all the existing node types * MFnDagNode dagNodeExist = new MFnDagNode(existingDagPath); * MObject existSurfObj = existingDagPath.node; * MFnDependencyNode depNodeExist = new MFnDependencyNode(existSurfObj); * * * updatedSurface = new MFnNurbsSurface(); * var newSurfObj = dagNodeExist.duplicate(); * updatedSurface.isIntermediateObject = true; * * updatedSurface.create(cvs, uknot, vknot, (uint)dynSurf.DegreeU, (uint)dynSurf.DegreeV, formU, formV, dynSurf.IsRational, newSurfObj); * MFnDependencyNode depNodeNew = new MFnDependencyNode(newSurfObj); * * MPlug outSurf = depNodeExist.findPlug("outputSurface"); * MPlug inSurf = depNodeNew.findPlug("inputSurface"); * * * mdgModifier.connect(outSurf, inSurf); * * * } */ mdgModifier.doIt(); // MFnDependencyNode nodeFn = new MFnDagNode(mSurf); //nodeFn.setName(name); //MGlobal.executeCommand("sets -e -forceElement initialShadingGroup " + nodeFn.name); } } else { if (checkNode.IsCompleted) { MFnNurbsSurface updatedSurface = new MFnNurbsSurface(); obj = updatedSurface.create(cvs, uknot, vknot, (uint)dynSurf.DegreeU, (uint)dynSurf.DegreeV, formU, formV, dynSurf.IsRational); MFnDependencyNode nodeFn = new MFnDagNode(obj); nodeFn.setName(name); MGlobal.executeCommand("sets -e -forceElement initialShadingGroup " + nodeFn.name); } } if (groupName != "") { bool groupExists = false; try { DMInterop.getDagNode(groupName); groupExists = true; } catch { } if (groupExists) { MGlobal.executeCommand(string.Format("parent {0} {1}", groupName, name)); } else { MGlobal.executeCommand(string.Format("group -n {0} {1}", groupName, name)); } } }
internal static void decomposeMayaCurve(MDagPath dagnode, MSpace.Space space, out Point3DCollection controlVertices, out List <double> weights, out List <double> knots, out int degree, out bool closed, out bool rational) { var nc = new MFnNurbsCurve(dagnode); var cvct = nc.numSpans; var p_aCVs = new MPointArray(); degree = nc.degree; closed = nc.form == MFnNurbsCurve.Form.kPeriodic ? true : false; rational = true; nc.getCVs(p_aCVs, space); controlVertices = new Point3DCollection(); weights = new List <double>(); if (MGlobal.isYAxisUp) { if (closed) { for (var i = 0; i < cvct; i++) { controlVertices.Add(new Point3D(p_aCVs[i].x, p_aCVs[i].y, p_aCVs[i].z)); weights.Add(1.0); } } else { foreach (var p in p_aCVs) { controlVertices.Add(new Point3D(p.x, p.y, p.z)); weights.Add(1.0); } } } else { if (closed) { for (var i = 0; i < cvct; i++) { controlVertices.Add(new Point3D(p_aCVs[i].x, -p_aCVs[i].z, p_aCVs[i].y)); weights.Add(1.0); } } else { foreach (var p in p_aCVs) { controlVertices.Add(new Point3D(p.x, -p.z, p.y)); weights.Add(1.0); } } } double min = 0, max = 0; nc.getKnotDomain(ref min, ref max); var d_aKnots = new MDoubleArray(); nc.getKnots(d_aKnots); knots = new List <double>(); knots.Add(min); knots.AddRange(d_aKnots); knots.Add(max); nc.Dispose(); d_aKnots.Dispose(); }
// // Description: // // Main selection routine // // Arguments: // // selectInfo - the selection state information // selectionList - the list of selected items to add to // worldSpaceSelectPts - // // Main selection routine // public override bool select(MSelectInfo selectInfo, MSelectionList selectionList, MPointArray worldSpaceSelectPts) { bool selected = false; bool componentSelected = false; bool hilited = false; hilited = (selectInfo.displayStatus == M3dView.DisplayStatus.kHilite); if ( hilited ) { componentSelected = selectVertices( selectInfo, selectionList, worldSpaceSelectPts ); selected = selected || componentSelected; } if ( !selected ) { apiMesh meshNode = (apiMesh)surfaceShape; // NOTE: If the geometry has an intersect routine it should // be called here with the selection ray to determine if the // the object was selected. selected = true; MSelectionMask priorityMask = new MSelectionMask( MSelectionMask.SelectionType.kSelectNurbsSurfaces ); MSelectionList item = new MSelectionList(); item.add( selectInfo.selectPath ); MPoint xformedPt = new MPoint(); if ( selectInfo.singleSelection ) { MPoint center = meshNode.boundingBox().center; xformedPt = center; xformedPt.multiplyEqual( selectInfo.selectPath.inclusiveMatrix ); } selectInfo.addSelection( item, xformedPt, selectionList, worldSpaceSelectPts, priorityMask, false ); } return selected; }
// // Description: // // Vertex selection. // // Arguments: // // selectInfo - the selection state information // selectionList - the list of selected items to add to // worldSpaceSelectPts - // public bool selectVertices( MSelectInfo selectInfo, MSelectionList selectionList, MPointArray worldSpaceSelectPts) { bool selected = false; M3dView view = selectInfo.view; MPoint xformedPoint = new MPoint(); MPoint selectionPoint = new MPoint(); double z = 0.0; double previousZ = 0.0; int closestPointVertexIndex = -1; MDagPath path = selectInfo.multiPath; // Create a component that will store the selected vertices // MFnSingleIndexedComponent fnComponent = new MFnSingleIndexedComponent(); MObject surfaceComponent = fnComponent.create( MFn.Type.kMeshVertComponent ); uint vertexIndex; // if the user did a single mouse click and we find > 1 selection // we will use the alignmentMatrix to find out which is the closest // MMatrix alignmentMatrix = new MMatrix(); MPoint singlePoint = new MPoint(); bool singleSelection = selectInfo.singleSelection; if( singleSelection ) { alignmentMatrix = selectInfo.alignmentMatrix; } // Get the geometry information // apiMesh meshNode = (apiMesh)surfaceShape; apiMeshGeom geom = meshNode.meshGeom(); // Loop through all vertices of the mesh and // see if they lie withing the selection area // uint numVertices = geom.vertices.length; for ( vertexIndex=0; vertexIndex<numVertices; vertexIndex++ ) { MPoint currentPoint = geom.vertices[ (int)vertexIndex ]; // Sets OpenGL's render mode to select and stores // selected items in a pick buffer // view.beginSelect(); OpenGL.glBegin(OpenGL.GL_POINTS); OpenGL.glVertex3f((float)currentPoint[0], (float)currentPoint[1], (float)currentPoint[2] ); OpenGL.glEnd(); if ( view.endSelect() > 0 ) // Hit count > 0 { selected = true; if ( singleSelection ) { xformedPoint = currentPoint; xformedPoint.homogenize(); xformedPoint.multiplyEqual( alignmentMatrix ); z = xformedPoint.z; if ( closestPointVertexIndex < 0 || z > previousZ ) { closestPointVertexIndex = (int)vertexIndex; singlePoint = currentPoint; previousZ = z; } } else { // multiple selection, store all elements // fnComponent.addElement( (int)vertexIndex ); } } } // If single selection, insert the closest point into the array // if ( selected && selectInfo.singleSelection ) { fnComponent.addElement(closestPointVertexIndex); // need to get world space position for this vertex // selectionPoint = singlePoint; selectionPoint.multiplyEqual( path.inclusiveMatrix ); } // Add the selected component to the selection list // if ( selected ) { MSelectionList selectionItem = new MSelectionList(); selectionItem.add( path, surfaceComponent ); MSelectionMask mask = new MSelectionMask( MSelectionMask.SelectionType.kSelectComponentsMask ); selectInfo.addSelection( selectionItem, selectionPoint, selectionList, worldSpaceSelectPts, mask, true ); } return selected; }
// // Description // // Transforms the given components. This method is used by // the move, rotate, and scale tools in component mode. // The bounding box has to be updated here, so do the normals and // any other attributes that depend on vertex positions. // // Arguments // mat - matrix to transform the components by // componentList - list of components to be transformed, // or an empty list to indicate the whole surface // cachingMode - how to use the supplied pointCache // pointCache - if non-null, save or restore points from this list base // on the cachingMode // public override void transformUsing(MMatrix mat, MObjectArray componentList, MVertexCachingMode cachingMode, MPointArray pointCache) { apiMeshGeom geomPtr = meshGeom(); bool savePoints = (cachingMode == MVertexCachingMode.kSavePoints); int i = 0, j = 0; uint len = componentList.length; if (cachingMode == MVertexCachingMode.kRestorePoints) { // restore the points based on the data provided in the pointCache attribute // uint cacheLen = pointCache.length; if (len > 0) { // traverse the component list // for ( i = 0; i < len && j < cacheLen; i++ ) { MObject comp = componentList[i]; MFnSingleIndexedComponent fnComp = new MFnSingleIndexedComponent( comp ); int elemCount = fnComp.elementCount; for ( int idx=0; idx<elemCount && j < cacheLen; idx++, ++j ) { int elemIndex = fnComp.element( idx ); geomPtr.vertices[elemIndex] = pointCache[j]; } } } else { // if the component list is of zero-length, it indicates that we // should transform the entire surface // len = geomPtr.vertices.length; for ( int idx = 0; idx < len && j < cacheLen; ++idx, ++j ) { geomPtr.vertices[idx] = pointCache[j]; } } } else { // Transform the surface vertices with the matrix. // If savePoints is true, save the points to the pointCache. // if (len > 0) { // Traverse the componentList // for ( i=0; i<len; i++ ) { MObject comp = componentList[i]; MFnSingleIndexedComponent fnComp = new MFnSingleIndexedComponent( comp ); uint elemCount = (uint)fnComp.elementCount; if (savePoints && 0 == i) { pointCache.sizeIncrement = elemCount; } for ( int idx=0; idx<elemCount; idx++ ) { int elemIndex = fnComp.element( (int)idx ); if (savePoints) { pointCache.append(geomPtr.vertices[elemIndex]); } geomPtr.vertices[elemIndex].multiplyEqual( mat ); geomPtr.normals[idx] = geomPtr.normals[idx].transformAsNormal( mat ); } } } else { // If the component list is of zero-length, it indicates that we // should transform the entire surface // len = geomPtr.vertices.length; if (savePoints) { pointCache.sizeIncrement = len; } for ( int idx = 0; idx < len; ++idx ) { if (savePoints) { pointCache.append(geomPtr.vertices[idx]); } geomPtr.vertices[idx].multiplyEqual( mat ); geomPtr.normals[idx] = geomPtr.normals[idx].transformAsNormal( mat ); } } } // Retrieve the value of the cached surface attribute. // We will set the new geometry data into the cached surface attribute // // Access the datablock directly. This code has to be efficient // and so we bypass the compute mechanism completely. // NOTE: In general we should always go though compute for getting // and setting attributes. // MDataBlock datablock = _forceCache(); MDataHandle cachedHandle = datablock.outputValue( cachedSurface ); apiMeshData cached = cachedHandle.asPluginData as apiMeshData; MDataHandle dHandle = datablock.outputValue( mControlPoints ); // If there is history then calculate the tweaks necessary for // setting the final positions of the vertices. // if ( hasHistory() && (null != cached) ) { // Since the shape has history, we need to store the tweaks (deltas) // between the input shape and the tweaked shape in the control points // attribute. // buildControlPoints( datablock, (int)geomPtr.vertices.length ); MArrayDataHandle cpHandle = new MArrayDataHandle( dHandle ); // Loop through the component list and transform each vertex. // for ( i=0; i<len; i++ ) { MObject comp = componentList[i]; MFnSingleIndexedComponent fnComp = new MFnSingleIndexedComponent( comp ); int elemCount = fnComp.elementCount; for ( int idx=0; idx<elemCount; idx++ ) { int elemIndex = fnComp.element( idx ); cpHandle.jumpToElement( (uint)elemIndex ); MDataHandle pntHandle = cpHandle.outputValue(); double[] pnt = pntHandle.Double3; MPoint oldPnt = cached.fGeometry.vertices[elemIndex]; MPoint newPnt = geomPtr.vertices[elemIndex]; MVector offset = newPnt.minus( oldPnt ); pnt[0] += offset[0]; pnt[1] += offset[1]; pnt[2] += offset[2]; pntHandle.Double3 = pnt; } } } // Copy outputSurface to cachedSurface // if ( null == cached ) { MGlobal.displayInfo("NULL cachedSurface data found"); } else { cached.fGeometry = geomPtr; } MPlug pCPs = new MPlug( thisMObject(), mControlPoints ); pCPs.setValue(dHandle); // Moving vertices will likely change the bounding box. // computeBoundingBox( datablock ); // Tell Maya the bounding box for this object has changed // and thus "boundingBox()" needs to be called. // childChanged( MChildChanged.kBoundingBoxChanged ); }
public static MDagPath CreateCurve(MPoint[] pts, string curveName, int degree = 1, MFnNurbsCurve.Form form = MFnNurbsCurve.Form.kOpen) { MPointArray points = new MPointArray(pts); return(CreateCurve(points, curveName, degree, form)); }
// // Description // // Constructs a cube // public void buildCube(double cube_size, MPointArray pa, MIntArray faceCounts, MIntArray faceConnects, MVectorArray normals, apiMeshGeomUV uvs) { const int num_faces = 6; const int num_face_connects = 24; const double normal_value = 0.5775; const int uv_count = 14; pa.clear(); faceCounts.clear(); faceConnects.clear(); uvs.reset(); pa.append( new MPoint( -cube_size, -cube_size, -cube_size ) ); pa.append( new MPoint( cube_size, -cube_size, -cube_size ) ); pa.append( new MPoint( cube_size, -cube_size, cube_size ) ); pa.append( new MPoint( -cube_size, -cube_size, cube_size ) ); pa.append( new MPoint( -cube_size, cube_size, -cube_size ) ); pa.append( new MPoint( -cube_size, cube_size, cube_size ) ); pa.append( new MPoint( cube_size, cube_size, cube_size ) ); pa.append( new MPoint( cube_size, cube_size, -cube_size ) ); normals.append( new MVector( -normal_value, -normal_value, -normal_value ) ); normals.append( new MVector( normal_value, -normal_value, -normal_value ) ); normals.append( new MVector( normal_value, -normal_value, normal_value ) ); normals.append( new MVector( -normal_value, -normal_value, normal_value ) ); normals.append( new MVector( -normal_value, normal_value, -normal_value ) ); normals.append( new MVector( -normal_value, normal_value, normal_value ) ); normals.append( new MVector( normal_value, normal_value, normal_value ) ); normals.append( new MVector( normal_value, normal_value, -normal_value ) ); // Define the UVs for the cube. // float[] uv_pts = new float[uv_count*2] { 0.375f, 0.0f, 0.625f, 0.0f, 0.625f, 0.25f, 0.375f, 0.25f, 0.625f, 0.5f, 0.375f, 0.5f, 0.625f, 0.75f, 0.375f, 0.75f, 0.625f, 1.0f, 0.375f, 1.0f, 0.875f, 0.0f, 0.875f, 0.25f, 0.125f, 0.0f, 0.125f, 0.25f }; // UV Face Vertex Id. // int[] uv_fvid = new int[num_face_connects]{ 0, 1, 2, 3, 3, 2, 4, 5, 5, 4, 6, 7, 7, 6, 8, 9, 1, 10, 11, 2, 12, 0, 3, 13 }; int i; for ( i = 0; i < uv_count; i ++ ) { uvs.append_uv( uv_pts[i*2], uv_pts[i*2 + 1] ); } for ( i = 0; i < num_face_connects; i ++ ) { uvs.faceVertexIndex.append( uv_fvid[i] ); } // Set up an array containing the number of vertices // for each of the 6 cube faces (4 vertices per face) // int[] face_counts = new int[num_faces]{ 4, 4, 4, 4, 4, 4 }; for ( i=0; i<num_faces; i++ ) { faceCounts.append( face_counts[i] ); } // Set up and array to assign vertices from pa to each face // int[] face_connects = new int[ num_face_connects ]{ 0, 1, 2, 3, 4, 5, 6, 7, 3, 2, 6, 5, 0, 3, 5, 4, 0, 4, 7, 1, 1, 7, 6, 2 }; for ( i=0; i<num_face_connects; i++ ) { faceConnects.append( face_connects[i] ); } }
// // Select function. Gets called when the bbox for the object is selected. // This function just selects the object without doing any intersection tests. // /* override */ public override bool select(MSelectInfo selectInfo, MSelectionList selectionList, MPointArray worldSpaceSelectPts) { MSelectionMask priorityMask = new MSelectionMask(MSelectionMask.SelectionType.kSelectObjectsMask); MSelectionList item = new MSelectionList(); item.add(selectInfo.selectPath); MPoint xformedPt = new MPoint(); selectInfo.addSelection(item, xformedPt, selectionList, worldSpaceSelectPts, priorityMask, false); return true; }
// // Description // // This function takes an input surface of type kMeshData and converts // the geometry into this nodes attributes. // Returns false if nothing is connected. // public bool computeInputMesh(MPlug plug, MDataBlock datablock, MPointArray vertices, MIntArray counts, MIntArray connects, MVectorArray normals, apiMeshGeomUV uvs) { // Get the input subdiv // MDataHandle inputData = datablock.inputValue( inputMesh ); MObject surf = inputData.asMesh; // Check if anything is connected // MObject thisObj = thisMObject(); MPlug surfPlug = new MPlug( thisObj, inputMesh ); if ( !surfPlug.isConnected ) { datablock.setClean( plug ); return false; } // Extract the mesh data // MFnMesh surfFn = new MFnMesh(surf); surfFn.getPoints( vertices, MSpace.Space.kObject ); // Check to see if we have UVs to copy. // bool hasUVs = surfFn.numUVsProperty > 0; surfFn.getUVs( uvs.ucoord, uvs.vcoord ); for ( int i=0; i<surfFn.numPolygons; i++ ) { MIntArray polyVerts = new MIntArray(); surfFn.getPolygonVertices( i, polyVerts ); int pvc = (int)polyVerts.length; counts.append( pvc ); int uvId; for ( int v=0; v<pvc; v++ ) { if ( hasUVs ) { surfFn.getPolygonUVid( i, v, out uvId ); uvs.faceVertexIndex.append( uvId ); } connects.append( polyVerts[v] ); } } for ( int n=0; n<(int)vertices.length; n++ ) { MVector normal = new MVector(); surfFn.getVertexNormal( n, normal ); normals.append( normal ); } return true; }
public static List <Surface> meshToNurbs(MFnMesh mayaMesh) { MFnSubd subDmesh = new MFnSubd(); subDmesh.isIntermediateObject = true; MPointArray mayaVerts = new MPointArray(); mayaMesh.getPoints(mayaVerts, MSpace.Space.kWorld); MIntArray polyVertct = new MIntArray(); MIntArray ids = new MIntArray(); MIntArray idList = new MIntArray(); for (int i = 0; i < mayaMesh.numPolygons; i++) { mayaMesh.getPolygonVertices(i, ids); foreach (var id in ids) { idList.Add(id); } polyVertct.Add(ids.Count); } subDmesh.createBaseMesh(false, mayaMesh.numVertices, mayaMesh.numPolygons, mayaVerts, polyVertct, idList); try { MUintArray creaseEdgId = new MUintArray(); MDoubleArray creaseEdgeVal = new MDoubleArray(); mayaMesh.getCreaseEdges(creaseEdgId, creaseEdgeVal); foreach (var edgId in creaseEdgId) { subDmesh.edgeSetCrease(edgId, true); } } catch {} try { MUintArray creaseVertId = new MUintArray(); MDoubleArray creaseVertVal = new MDoubleArray(); mayaMesh.getCreaseVertices(creaseVertId, creaseVertVal); foreach (var vertId in creaseVertId) { subDmesh.vertexSetCrease(vertId, true); } } catch { } subDmesh.updateAllEditsAndCreases(); MObjectArray nurbsSurfs = new MObjectArray(); subDmesh.convertToNurbs(nurbsSurfs); List <MFnNurbsSurface> mfnSurfaceList = new List <MFnNurbsSurface>(nurbsSurfs.Count); foreach (var surf in nurbsSurfs) { mfnSurfaceList.Add(new MFnNurbsSurface(surf)); } List <Surface> dynSurfaceList = new List <Surface>(mfnSurfaceList.Count); foreach (var mfnNS in mfnSurfaceList) { dynSurfaceList.Add(DMSurface.mNurbsSurfaceToDynamoSurface(mfnNS, MSpace.Space.kObject)); } MGlobal.deleteNode(subDmesh.model); return(dynSurfaceList); }
public TriMesh ConvertTriMesh(MFnMesh mesh) { if(mesh==null) { MGlobal.displayInfo("Mesh is null \n"); } TriMesh trimesh = new TriMesh(); MIntArray indices = new MIntArray(); MIntArray triangleCounts = new MIntArray(); MPointArray points = new MPointArray(); mesh.getTriangles(triangleCounts, indices); mesh.getPoints(points); // Get the triangle indices for (int i = 0; i < (int)points.length; ++i) { MPoint pt = points[i]; VertexTraits trait = new VertexTraits(pt.x, pt.y, pt.z); trimesh.Vertices.Add(trait); } MGlobal.displayInfo( indices.Count.ToString() +"\n"); int j=0; while(j<indices.Count) { int a = indices[j]; j++; int b = indices[j]; j++; int c = indices[j]; j++; trimesh.Faces.AddTriangles(trimesh.Vertices[a], trimesh.Vertices[b], trimesh.Vertices[c]); } return trimesh; }
public override void tweakUsing( MMatrix mat, MObjectArray componentList, MVertexCachingMode cachingMode, MPointArray pointCache, MArrayDataHandle handle ) // // Description // // Transforms the given components. This method is used by // the move, rotate, and scale tools in component mode when the // tweaks for the shape are stored on a separate tweak node. // The bounding box has to be updated here, so do the normals and // any other attributes that depend on vertex positions. // // Arguments // mat - matrix to transform the components by // componentList - list of components to be transformed, // or an empty list to indicate the whole surface // cachingMode - how to use the supplied pointCache // pointCache - if non-null, save or restore points from this list base // on the cachingMode // handle - handle to the attribute on the tweak node where the // tweaks should be stored // { apiMeshGeom geomPtr = meshGeom(); bool savePoints = (cachingMode == MVertexCachingMode.kSavePoints); bool updatePoints = (cachingMode == MVertexCachingMode.kUpdatePoints); MArrayDataBuilder builder = handle.builder(); MPoint delta = new MPoint(); MPoint currPt = new MPoint(); MPoint newPt = new MPoint(); int i=0; uint len = componentList.length; int cacheIndex = 0; uint cacheLen = (null != pointCache) ? pointCache.length : 0; if (cachingMode == MVertexCachingMode.kRestorePoints) { // restore points from the pointCache // if (len > 0) { // traverse the component list // for ( i=0; i<len; i++ ) { MObject comp = componentList[i]; MFnSingleIndexedComponent fnComp = new MFnSingleIndexedComponent( comp ); int elemCount = fnComp.elementCount; for ( int idx=0; idx<elemCount && cacheIndex < cacheLen; idx++, cacheIndex++) { int elemIndex = fnComp.element( idx ); MDataHandle hdl = builder.addElement((uint)elemIndex); double[] pt = hdl.Double3; MPoint cachePt = pointCache[cacheIndex]; pt[0] += cachePt.x; pt[1] += cachePt.y; pt[2] += cachePt.z; hdl.Double3 = pt; } } } else { // if the component list is of zero-length, it indicates that we // should transform the entire surface // len = geomPtr.vertices.length; for ( uint idx = 0; idx < len && idx < cacheLen; ++idx ) { MDataHandle hdl = builder.addElement(idx); double[] pt = hdl.Double3; MPoint cachePt = pointCache[cacheIndex]; pt[0] += cachePt.x; pt[1] += cachePt.y; pt[2] += cachePt.z; hdl.Double3 = pt; } } } else { // Tweak the points. If savePoints is true, also save the tweaks in the // pointCache. If updatePoints is true, add the new tweaks to the existing // data in the pointCache. // if (len > 0) { for ( i=0; i<len; i++ ) { MObject comp = componentList[i]; MFnSingleIndexedComponent fnComp = new MFnSingleIndexedComponent( comp ); int elemCount = fnComp.elementCount; if (savePoints) { pointCache.sizeIncrement = (uint)elemCount; } for ( int idx=0; idx<elemCount; idx++ ) { int elemIndex = fnComp.element( idx ); MDataHandle hdl = builder.addElement((uint)elemIndex); double[] pt = hdl.Double3; currPt = newPt = geomPtr.vertices[elemIndex]; newPt.multiplyEqual( mat ); delta.x = newPt.x - currPt.x; delta.y = newPt.y - currPt.y; delta.z = newPt.z - currPt.z; pt[0] += delta.x; pt[1] += delta.y; pt[2] += delta.z; hdl.Double3 = pt; if (savePoints) { // store the points in the pointCache for undo // pointCache.append(delta*(-1.0)); } else if (updatePoints && cacheIndex < cacheLen) { MPoint cachePt = pointCache[cacheIndex]; cachePt[0] -= delta.x; cachePt[1] -= delta.y; cachePt[2] -= delta.z; cacheIndex++; } } } } else { // if the component list is of zero-length, it indicates that we // should transform the entire surface // len = geomPtr.vertices.length; if (savePoints) { pointCache.sizeIncrement = len; } for ( int idx = 0; idx < len; ++idx ) { MDataHandle hdl = builder.addElement((uint)idx); double[] pt = hdl.Double3; currPt = newPt = geomPtr.vertices[idx]; newPt.multiplyEqual( mat ); delta.x = newPt.x - currPt.x; delta.y = newPt.y - currPt.y; delta.z = newPt.z - currPt.z; pt[0] += delta.x; pt[1] += delta.y; pt[2] += delta.z; hdl.Double3 = pt; if (savePoints) { // store the points in the pointCache for undo // pointCache.append(delta*-1.0); } else if (updatePoints && idx < cacheLen) { MPoint cachePt = pointCache[idx]; cachePt[0] -= delta.x; cachePt[1] -= delta.y; cachePt[2] -= delta.z; } } } } // Set the builder into the handle. // handle.set(builder); // Tell Maya the bounding box for this object has changed // and thus "boundingBox()" needs to be called. // childChanged( MChildChanged.kBoundingBoxChanged ); }
static public MPointArray ComputeData(MPointArray inPos, float angle, float envolope) { var memorySize = inPos.Count * 4 * sizeof(float); float[] ubo = { inPos.Count, angle, envolope }; // pos to float[] float[] allPos = new float[inPos.Count * 4]; var i = 0; foreach (var point in inPos) { allPos[i * 4 + 0] = (float)point.x; allPos[i * 4 + 1] = (float)point.y; allPos[i * 4 + 2] = (float)point.z; allPos[i * 4 + 3] = (float)point.w; i++; } var instance = new Instance(new InstanceCreateInfo { ApplicationInfo = new ApplicationInfo { ApplicationName = "CSharp Vulkan", ApplicationVersion = Vulkan.Version.Make(1, 0, 0), ApiVersion = Vulkan.Version.Make(1, 0, 0), EngineName = "CSharp Engine", EngineVersion = Vulkan.Version.Make(1, 0, 0) }, //EnabledExtensionCount = 0, //EnabledLayerCount = 0 EnabledExtensionNames = new string[] { "VK_EXT_debug_report" }, EnabledLayerNames = new string[] { "VK_LAYER_LUNARG_standard_validation" } }); var debugCallback = new Instance.DebugReportCallback(DebugReportCallback); instance.EnableDebug(debugCallback, DebugReportFlagsExt.Warning | DebugReportFlagsExt.Error); PhysicalDevice physicalDevice = instance.EnumeratePhysicalDevices()[0]; var queueFamilyIndex = FindBestComputeQueue(physicalDevice); DeviceQueueCreateInfo[] deviceQueueCreateInfo = { new DeviceQueueCreateInfo { QueueFamilyIndex = queueFamilyIndex, QueueCount = 1, QueuePriorities = new float[] { 1.0f } } }; var deviceCreateInfo = new DeviceCreateInfo { QueueCreateInfos = deviceQueueCreateInfo, EnabledFeatures = new PhysicalDeviceFeatures(), EnabledExtensionCount = 0, //EnabledLayerCount = 0 //EnabledExtensionNames = new string[] { "VK_EXT_debug_report" }, EnabledLayerNames = new string[] { "VK_LAYER_LUNARG_standard_validation" } }; var device = physicalDevice.CreateDevice(deviceCreateInfo); //var memProperties = physicalDevice.GetMemoryProperties(); var bufferCreateInfo = new BufferCreateInfo { Size = memorySize, Usage = BufferUsageFlags.StorageBuffer, SharingMode = SharingMode.Exclusive, QueueFamilyIndices = new uint[] { queueFamilyIndex } }; var inBuffer = device.CreateBuffer(bufferCreateInfo); var outBuffer = device.CreateBuffer(bufferCreateInfo); var memRequirements = device.GetBufferMemoryRequirements(inBuffer); uint memIndex = FindMemoryType(physicalDevice, memRequirements.MemoryTypeBits, MemoryPropertyFlags.HostVisible | MemoryPropertyFlags.HostCoherent); var memoryAllocatInfo = new MemoryAllocateInfo { AllocationSize = memRequirements.Size, MemoryTypeIndex = memIndex }; var memory = device.AllocateMemory(memoryAllocatInfo); var dataPtr = device.MapMemory(memory, 0, memorySize); Marshal.Copy(allPos, 0, dataPtr, allPos.Length); device.UnmapMemory(memory); memRequirements = device.GetBufferMemoryRequirements(outBuffer); memoryAllocatInfo.MemoryTypeIndex = FindMemoryType(physicalDevice, memRequirements.MemoryTypeBits, MemoryPropertyFlags.HostVisible | MemoryPropertyFlags.HostCoherent); var outMemory = device.AllocateMemory(memoryAllocatInfo); device.BindBufferMemory(inBuffer, memory, 0); device.BindBufferMemory(outBuffer, outMemory, 0); //var uboSize = Marshal.SizeOf(ubo); var uboSize = 3 * sizeof(float); var uboBufferCreateInfo = new BufferCreateInfo { Size = uboSize, Usage = BufferUsageFlags.UniformBuffer, SharingMode = SharingMode.Exclusive, QueueFamilyIndices = new uint[] { queueFamilyIndex } }; var uboBuffer = device.CreateBuffer(uboBufferCreateInfo); memRequirements = device.GetBufferMemoryRequirements(uboBuffer); var uboMemoryAllocInfo = new MemoryAllocateInfo { AllocationSize = memRequirements.Size, MemoryTypeIndex = FindMemoryType(physicalDevice, memRequirements.MemoryTypeBits, MemoryPropertyFlags.HostVisible | MemoryPropertyFlags.HostCoherent) }; var uboMemory = device.AllocateMemory(uboMemoryAllocInfo); var uboPtr = device.MapMemory(uboMemory, 0, uboSize); Marshal.Copy(ubo, 0, uboPtr, ubo.Length); device.UnmapMemory(uboMemory); device.BindBufferMemory(uboBuffer, uboMemory, 0); //string textureName = string.Format("{0}.comp.spv", typeof(VulankCompute).Namespace); //Stream stream = typeof(VulankCompute).GetTypeInfo().Assembly.GetManifestResourceStream(textureName); string shaderFile = @"E:\coding\CShape\yTwistCSharpVulkan\comp.spv"; Stream stream = File.Open(shaderFile, FileMode.Open); byte[] shaderCode = new byte[stream.Length]; stream.Read(shaderCode, 0, (int)stream.Length); stream.Close(); stream.Dispose(); var shaderModule = device.CreateShaderModule(shaderCode); DescriptorSetLayoutBinding[] descriptorSetLayoutBindings = { new DescriptorSetLayoutBinding { Binding = 0, DescriptorType = DescriptorType.StorageBuffer, DescriptorCount = 1, StageFlags = ShaderStageFlags.Compute }, new DescriptorSetLayoutBinding { Binding = 1, DescriptorType = DescriptorType.StorageBuffer, DescriptorCount = 1, StageFlags = ShaderStageFlags.Compute }, new DescriptorSetLayoutBinding { Binding = 2, DescriptorType = DescriptorType.UniformBuffer, DescriptorCount = 1, StageFlags = ShaderStageFlags.Compute } }; var descriporSetLayoutCreateinfo = new DescriptorSetLayoutCreateInfo { Bindings = descriptorSetLayoutBindings }; var descriptorSetLayout = device.CreateDescriptorSetLayout(descriporSetLayoutCreateinfo); var descriptorPool = device.CreateDescriptorPool(new DescriptorPoolCreateInfo { MaxSets = 1, PoolSizes = new DescriptorPoolSize[] { new DescriptorPoolSize { DescriptorCount = 3 } } }); var descriptorSet = device.AllocateDescriptorSets(new DescriptorSetAllocateInfo { DescriptorPool = descriptorPool, SetLayouts = new DescriptorSetLayout[] { descriptorSetLayout } })[0]; var inBufferInfo = new DescriptorBufferInfo { Buffer = inBuffer, Offset = 0, Range = memorySize }; var outBufferInfo = new DescriptorBufferInfo { Buffer = outBuffer, Offset = 0, Range = memorySize }; var uboBufferInfo = new DescriptorBufferInfo { Buffer = uboBuffer, Offset = 0, Range = uboSize }; WriteDescriptorSet[] writeDescriptorSets = { new WriteDescriptorSet { DstSet = descriptorSet, DstBinding = 0, DstArrayElement = 0, DescriptorCount = 1, DescriptorType = DescriptorType.StorageBuffer, BufferInfo = new DescriptorBufferInfo[] { inBufferInfo } }, new WriteDescriptorSet { DstSet = descriptorSet, DstBinding = 1, DstArrayElement = 0, DescriptorCount = 1, DescriptorType = DescriptorType.StorageBuffer, BufferInfo = new DescriptorBufferInfo[] { outBufferInfo } }, new WriteDescriptorSet { DstSet = descriptorSet, DstBinding = 2, DstArrayElement = 0, DescriptorCount = 1, DescriptorType = DescriptorType.UniformBuffer, BufferInfo = new DescriptorBufferInfo[] { uboBufferInfo } } }; device.UpdateDescriptorSets(writeDescriptorSets, null); var pipelineLayout = device.CreatePipelineLayout(new PipelineLayoutCreateInfo { SetLayouts = new DescriptorSetLayout[] { descriptorSetLayout } }); var shaderStage = new PipelineShaderStageCreateInfo { Stage = ShaderStageFlags.Compute, Module = shaderModule, Name = "main" }; var pipeline = device.CreateComputePipelines(null, new ComputePipelineCreateInfo[] { new ComputePipelineCreateInfo { Stage = shaderStage, Layout = pipelineLayout } })[0]; var commandPool = device.CreateCommandPool(new CommandPoolCreateInfo { QueueFamilyIndex = queueFamilyIndex }); var cmdBuffer = device.AllocateCommandBuffers(new CommandBufferAllocateInfo { CommandPool = commandPool, CommandBufferCount = 1, Level = CommandBufferLevel.Primary })[0]; cmdBuffer.Begin(new CommandBufferBeginInfo { Flags = CommandBufferUsageFlags.OneTimeSubmit }); cmdBuffer.CmdBindPipeline(PipelineBindPoint.Compute, pipeline); cmdBuffer.CmdBindDescriptorSet(PipelineBindPoint.Compute, pipelineLayout, 0, descriptorSet, null); cmdBuffer.CmdDispatch((uint)inPos.Count, 1, 1); cmdBuffer.End(); var queue = device.GetQueue(queueFamilyIndex, 0); //var fence = device.CreateFence(new FenceCreateInfo { Flags=0 }); queue.Submit(new SubmitInfo { WaitSemaphoreCount = 0, CommandBuffers = new CommandBuffer[] { cmdBuffer }, }); queue.WaitIdle(); //device.WaitForFence(fence, true, UInt64.MaxValue); var newDataPtr = device.MapMemory(outMemory, 0, memorySize); Marshal.Copy(newDataPtr, allPos, 0, allPos.Length); device.UnmapMemory(outMemory); var j = 0; foreach (var p in inPos) { p.x = allPos[j * 4 + 0]; p.y = allPos[j * 4 + 1]; p.z = allPos[j * 4 + 2]; p.w = allPos[j * 4 + 3]; j++; } //device.DestroyFence(fence); device.DestroyShaderModule(shaderModule); device.DestroyCommandPool(commandPool); device.DestroyDescriptorSetLayout(descriptorSetLayout); device.DestroyDescriptorPool(descriptorPool); device.DestroyPipelineLayout(pipelineLayout); device.DestroyPipeline(pipeline); device.DestroyBuffer(inBuffer); device.DestroyBuffer(outBuffer); device.DestroyBuffer(uboBuffer); device.FreeMemory(memory); device.FreeMemory(outMemory); device.FreeMemory(uboMemory); device.Destroy(); //instance.Destroy(); return(inPos); }
// // Description // // Transforms the given components. This method is used by // the move, rotate, and scale tools in component mode when the // tweaks for the shape are stored on a separate tweak node. // The bounding box has to be updated here, so do the normals and // any other attributes that depend on vertex positions. // // Arguments // mat - matrix to transform the components by // componentList - list of components to be transformed, // or an empty list to indicate the whole surface // cachingMode - how to use the supplied pointCache // pointCache - if non-null, save or restore points from this list base // on the cachingMode // handle - handle to the attribute on the tweak node where the // tweaks should be stored // public override void tweakUsing( MMatrix mat, MObjectArray componentList, MVertexCachingMode cachingMode, MPointArray pointCache, MArrayDataHandle handle) { apiMeshGeom geomPtr = meshGeom(); bool savePoints = (cachingMode == MVertexCachingMode.kSavePoints); bool updatePoints = (cachingMode == MVertexCachingMode.kUpdatePoints); MArrayDataBuilder builder = handle.builder(); MPoint delta = new MPoint(); MPoint currPt = new MPoint(); MPoint newPt = new MPoint(); int i=0; uint len = componentList.length; int cacheIndex = 0; uint cacheLen = (null != pointCache) ? pointCache.length : 0; if (cachingMode == MVertexCachingMode.kRestorePoints) { // restore points from the pointCache // if (len > 0) { // traverse the component list // for ( i=0; i<len; i++ ) { MObject comp = componentList[i]; MFnSingleIndexedComponent fnComp = new MFnSingleIndexedComponent( comp ); int elemCount = fnComp.elementCount; for ( int idx=0; idx<elemCount && cacheIndex < cacheLen; idx++, cacheIndex++) { int elemIndex = fnComp.element( idx ); MDataHandle hdl = builder.addElement((uint)elemIndex); double[] pt = hdl.Double3; MPoint cachePt = pointCache[cacheIndex]; pt[0] += cachePt.x; pt[1] += cachePt.y; pt[2] += cachePt.z; hdl.Double3 = pt; } } } else { // if the component list is of zero-length, it indicates that we // should transform the entire surface // len = geomPtr.vertices.length; for ( uint idx = 0; idx < len && idx < cacheLen; ++idx ) { MDataHandle hdl = builder.addElement(idx); double[] pt = hdl.Double3; MPoint cachePt = pointCache[cacheIndex]; pt[0] += cachePt.x; pt[1] += cachePt.y; pt[2] += cachePt.z; hdl.Double3 = pt; } } } else { // Tweak the points. If savePoints is true, also save the tweaks in the // pointCache. If updatePoints is true, add the new tweaks to the existing // data in the pointCache. // if (len > 0) { for ( i=0; i<len; i++ ) { MObject comp = componentList[i]; MFnSingleIndexedComponent fnComp = new MFnSingleIndexedComponent( comp ); int elemCount = fnComp.elementCount; if (savePoints) { pointCache.sizeIncrement = (uint)elemCount; } for ( int idx=0; idx<elemCount; idx++ ) { int elemIndex = fnComp.element( idx ); MDataHandle hdl = builder.addElement((uint)elemIndex); double[] pt = hdl.Double3; currPt = newPt = geomPtr.vertices[elemIndex]; newPt.multiplyEqual( mat ); delta.x = newPt.x - currPt.x; delta.y = newPt.y - currPt.y; delta.z = newPt.z - currPt.z; pt[0] += delta.x; pt[1] += delta.y; pt[2] += delta.z; hdl.Double3 = pt; if (savePoints) { // store the points in the pointCache for undo // pointCache.append(delta*(-1.0)); } else if (updatePoints && cacheIndex < cacheLen) { MPoint cachePt = pointCache[cacheIndex]; cachePt[0] -= delta.x; cachePt[1] -= delta.y; cachePt[2] -= delta.z; cacheIndex++; } } } } else { // if the component list is of zero-length, it indicates that we // should transform the entire surface // len = geomPtr.vertices.length; if (savePoints) { pointCache.sizeIncrement = len; } for ( int idx = 0; idx < len; ++idx ) { MDataHandle hdl = builder.addElement((uint)idx); double[] pt = hdl.Double3; currPt = newPt = geomPtr.vertices[idx]; newPt.multiplyEqual( mat ); delta.x = newPt.x - currPt.x; delta.y = newPt.y - currPt.y; delta.z = newPt.z - currPt.z; pt[0] += delta.x; pt[1] += delta.y; pt[2] += delta.z; hdl.Double3 = pt; if (savePoints) { // store the points in the pointCache for undo // pointCache.append(delta*-1.0); } else if (updatePoints && idx < cacheLen) { MPoint cachePt = pointCache[idx]; cachePt[0] -= delta.x; cachePt[1] -= delta.y; cachePt[2] -= delta.z; } } } } // Set the builder into the handle. // handle.set(builder); // Tell Maya the bounding box for this object has changed // and thus "boundingBox()" needs to be called. // childChanged( MChildChanged.kBoundingBoxChanged ); }
// // Description // // Create circles of vertices starting with // the top pole ending with the bottom pole // public void buildSphere(double rad, int div, MPointArray vertices, MIntArray counts, MIntArray connects, MVectorArray normals, apiMeshGeomUV uvs) { double u = -Math.PI / 2.0; double v = -Math.PI; double u_delta = Math.PI / ((double)div); double v_delta = 2 * Math.PI / ((double)div); MPoint topPole = new MPoint(0.0, rad, 0.0); MPoint botPole = new MPoint(0.0, -rad, 0.0); // Build the vertex and normal table // vertices.append(botPole); normals.append(botPole.minus(MPoint.origin)); int i; for (i = 0; i < (div - 1); i++) { u += u_delta; v = -Math.PI; for (int j = 0; j < div; j++) { double x = rad * Math.Cos(u) * Math.Cos(v); double y = rad * Math.Sin(u); double z = rad * Math.Cos(u) * Math.Sin(v); MPoint pnt = new MPoint(x, y, z); vertices.append(pnt); normals.append(pnt.minus(MPoint.origin)); v += v_delta; } } vertices.append(topPole); normals.append(topPole.minus(MPoint.origin)); // Create the connectivity lists // int vid = 1; int numV = 0; for (i = 0; i < div; i++) { for (int j = 0; j < div; j++) { if (i == 0) { counts.append(3); connects.append(0); connects.append(j + vid); connects.append((j == (div - 1)) ? vid : j + vid + 1); } else if (i == (div - 1)) { counts.append(3); connects.append(j + vid + 1 - div); connects.append(vid + 1); connects.append(j == (div - 1) ? vid + 1 - div : j + vid + 2 - div); } else { counts.append(4); connects.append(j + vid + 1 - div); connects.append(j + vid + 1); connects.append(j == (div - 1) ? vid + 1 : j + vid + 2); connects.append(j == (div - 1) ? vid + 1 - div : j + vid + 2 - div); } numV++; } vid = numV; } // TODO: Define UVs for sphere ... // }