Пример #1
0
	// grab the current mesh and setup the polygon sets
	void Mesh::SetMesh(const MDagPath &dPath) {
		MObjectArray fPolygonSets;
		MObjectArray fPolygonComponents;
		MDagPath dagPath(dPath);
		polySets.clear();
		
		MFnMesh fMesh = MFnMesh(dagPath);
		
		//Have to make the path include the shape below it so that
		//we can determine if the underlying shape node is instanced.
		//By default, dag paths only include transform nodes.
		dagPath.extendToShape();

		//If the shape is instanced then we need to determine which instance this path refers to.
		int instanceNum = 0;
		if (dagPath.isInstanced())
			instanceNum = dagPath.instanceNumber();

		//Get the connected sets and members - these will be used to determine texturing of different faces
		if (!fMesh.getConnectedSetsAndMembers(instanceNum, fPolygonSets, fPolygonComponents, true)) {
			MGlobal::displayError("MFnMesh::getConnectedSetsAndMembers"); 
			return;
		}
		
		unsigned int setCount = fPolygonSets.length();
		if (setCount > 1)
			setCount--;
		
		for (unsigned int i=0; i < setCount; i++)
			polySets.push_back(PolygonSet(dagPath, fPolygonComponents[i], fPolygonSets[i]));
		
	}
MStatus	liqAttachPrefAttribute::redoIt()
{
  MFnTypedAttribute tAttr;
  MStatus status;

  for ( unsigned i( 0 ); i < objectNames.length(); i++ ) 
  {
    MSelectionList		nodeList;
    nodeList.add( objectNames[i] );
    MObject depNodeObj;
    nodeList.getDependNode( 0, depNodeObj );
    MDagPath dagNode;
    nodeList.getDagPath( 0, dagNode );
    MFnDependencyNode depNode( depNodeObj );
    MObject prefAttr;
    MString attrName, varName;

    // make sure the renderer description is up to date
    liqglo.liquidRenderer.setRenderer();

    // build the name of the attribute
    varName = ( ( exportN && depNodeObj.hasFn( MFn::kMesh ) )? "N":"P" );
    attrName = "rman";
    attrName += varName;
    attrName += ( ( liqglo.liquidRenderer.requires__PREF )? "__":"" );
    attrName += varName + "ref";

    // create the attribute
    prefAttr = tAttr.create( attrName, attrName, MFnData::kPointArray );


    if ( depNodeObj.hasFn( MFn::kNurbsSurface ) ) 
    {
      MFnNurbsSurface nodeFn( depNodeObj );
      MPointArray nodePArray;
      MItSurfaceCV cvs( dagNode, MObject::kNullObj, liqglo.liquidRenderer.requires_SWAPPED_UVS == false, &status );

      while( !cvs.isDone() ) 
      {
        while( !cvs.isRowDone() ) 
        {
          MPoint pt = (worldSpace)? cvs.position( MSpace::kWorld ) : cvs.position( MSpace::kObject );
          nodePArray.append( pt );
          cvs.next();
        }
        cvs.nextRow();
      }

      nodeFn.addAttribute( prefAttr );
      MFnPointArrayData pArrayData;

      MObject prefDefault = pArrayData.create( nodePArray );
      MPlug nodePlug( depNodeObj, prefAttr );
      nodePlug.setValue( prefDefault );
    } 
    else if ( depNodeObj.hasFn( MFn::kNurbsCurve ) ) 
    {
      // Carsten: added support for PREF on nurbs curves
      //
      MFnNurbsCurve nodeFn( depNodeObj );
      MPointArray nodePArray;
      nodeFn.getCVs( nodePArray );

      nodeFn.addAttribute( prefAttr );
      MFnPointArrayData pArrayData;

      MObject prefDefault = pArrayData.create( nodePArray );
      MPlug nodePlug( depNodeObj, prefAttr );
      nodePlug.setValue( prefDefault );
    } 
    else if ( depNodeObj.hasFn( MFn::kMesh ) ) 
    {
      MFnMesh nodeFn( depNodeObj );
      // Moritz: modified this line to dim nodePArray -- otherwise
      // nodePArray.set() in the wile loop below throws an exception
      // which was why __Pref didn't work
      MPointArray nodePArray( MFnMesh( depNodeObj ).numVertices() );
      unsigned count;

      nodeFn.addAttribute( prefAttr );

      if ( exportN ) 
      {
        // export Nref
        unsigned vertex;
        unsigned normal;
        unsigned face = 0;
        unsigned faceVertex = 0;
        unsigned int numNormals = nodeFn.numNormals();
        unsigned int numPoints  = nodeFn.numVertices();
        MFloatVectorArray normals;
        MVectorArray normalAttArray;
        nodeFn.getNormals( normals );

        if ( numNormals > numPoints ) 
        {
          // if we get more than 1 normal per vertex,
          // force the arraysize to the full facevarying size
          unsigned faceVaryingCount( 0 );
          for ( unsigned pOn( 0 ); pOn < nodeFn.numPolygons(); pOn++ ) 
            faceVaryingCount += nodeFn.polygonVertexCount( pOn );
          
          normalAttArray.setLength( faceVaryingCount );
        } 
        else 
          normalAttArray.setLength(normals.length());
        
        for ( MItMeshPolygon polyIt ( depNodeObj ); polyIt.isDone() == false; polyIt.next() ) 
        {
          count = polyIt.polygonVertexCount();
          while ( count > 0 ) 
          {
            --count;
            normal = polyIt.normalIndex( count );
            vertex = polyIt.vertexIndex( count );

            if( numNormals == numPoints )
              normalAttArray.set(normals[normal], vertex);
            else
              normalAttArray.set(normals[normal], faceVertex);

            ++faceVertex;
          }
          ++face;
        }

        MFnVectorArrayData pArrayData;
        MObject prefDefault = pArrayData.create( normalAttArray );
        MPlug nodePlug( depNodeObj, prefAttr );
        nodePlug.setValue( prefDefault );

      } 
      else 
      {
        // TODO: do we need to account for the altMeshExport algo that's
        // used in liquidRibMeshData?
        // Moritz: no, it's basically the same as the algo below
        for ( MItMeshPolygon polyIt( dagNode, MObject::kNullObj ); !polyIt.isDone(); polyIt.next()) 
        {
          count = polyIt.polygonVertexCount();

          while ( count > 0 ) 
          {
            --count;
            unsigned	vertexIndex = polyIt.vertexIndex( count );
            MPoint nodePoint = (worldSpace)? polyIt.point( count, MSpace::kWorld ) : polyIt.point( count, MSpace::kObject );
            // Moritz: this returns MS::kFailure but seems to work?!
            nodePArray.set( nodePoint, vertexIndex );
          }
        }

        MFnPointArrayData pArrayData;
        MObject prefDefault = pArrayData.create( nodePArray );
        MPlug nodePlug( depNodeObj, prefAttr );
        nodePlug.setValue( prefDefault );

      }
    } else cerr << "Neither a Nurbs nor a Mesh !!" << endl;
  }
  return MS::kSuccess;
}
Пример #3
0
bool CSGSlicer::slice( const Cell& cell, const MeshSlicerInfo& info, MFnMesh& outMesh ) {
	// copy maya mesh to csg.js model
	csgjs_model jsModel;
	MItMeshVertex it(_sourceMesh);
	while( !it.isDone() ) {
		csgjs_vertex vtx;
		// get position
		MPoint pos = it.position(MSpace::kWorld);
		vtx.pos = csgjs_vector(static_cast<float>(pos.x), static_cast<float>(pos.y), static_cast<float>(pos.z));
		// add position
		jsModel.vertices.push_back(vtx);
		it.next();
	}
	MIntArray triangleCounts;
	MIntArray triangleVertices;
	MFnMesh(_sourceMesh).getTriangles(triangleCounts, triangleVertices);
	for( unsigned int i = 0; i < triangleVertices.length(); ++i ) {
		jsModel.indices.push_back(triangleVertices[i]);
	}

	// convert cell into csgjs_model
	csgjs_model cellModel;

	int indexOffset = 0;
	const auto& planePoints = cell.getPlanePoints();
	for( const auto& points : planePoints ) {
		for( const auto& pnt : points ) {
			csgjs_vertex vtx;
			vtx.pos = csgjs_vector(pnt.x, pnt.y, pnt.z);
			cellModel.vertices.push_back(vtx);
		}
		const auto& indices = HadanConvexTriangulate(points);
		for( const auto& idx : indices ) {
			cellModel.indices.push_back(indexOffset + idx[0]);
			cellModel.indices.push_back(indexOffset + idx[1]);
			cellModel.indices.push_back(indexOffset + idx[2]);
		}

		indexOffset += static_cast<int>(points.size());
	}

	// perform intersection
	const csgjs_model result = csgjs_intersection(jsModel, cellModel);

	// copy back to maya mesh
	MPointArray pointArray;
	for( const auto& vtx : result.vertices ) {
		pointArray.append(MPoint(vtx.pos.x, vtx.pos.y, vtx.pos.z));
	}
	MIntArray faceConnects;
	for( const auto& idx : result.indices ) {
		faceConnects.append(idx);
	}
	MIntArray faceCounts;
	for( size_t i = 0; i < result.indices.size() / 3; ++i ) {
		faceCounts.append(3);
	}
	{
		std::unique_lock<std::mutex> lock(CSGJS_CREATEMESH_MUTEX);
		outMesh.create(pointArray.length(), faceCounts.length(), pointArray, faceCounts, faceConnects);
	}

	return true;
}