Beispiel #1
0
MStatus compute_halfedge_indices(MIntArray &nFV, MIntArray &F, MIntArray &selV, MIntArray &selF, MIntArray &selHE)
{
    MIntArray F2H(nFV.length(), 0);
    
    size_t cumsum = 0;
    for (size_t k=0; k<nFV.length(); k++)
    {
        F2H[k] = cumsum; 
        cumsum += nFV[k];
    }
    
    selHE.setLength(selF.length());
    for (size_t k=0; k<selF.length(); k++)
    {
        size_t cV = selV[k];
        size_t cF = selF[k];
        size_t cnFV = nFV[cF];
        size_t cF2H = F2H[cF];
        for (size_t kFV=0; kFV<cnFV; kFV++)
        {
            if (F[cF2H+kFV]==cV)
            {
                selHE[k] = cF2H + kFV; break;
            }
        }
    }
    
    return MS::kSuccess;
}
// ----------------------------------------
bool GeometryPolygonExporter::getPolygonVertexCount(
    MItMeshPolygon &meshPolygonsIter,
    unsigned long &numVertices )
{
    bool addVertexCount = false;

    // Establish the number of vertexes in the polygon.
    // We don't need the vertex count list for triangulation
    if ( triangulated ) return addVertexCount;

    // The number of vertices
    numVertices = 0;

    // Retrieve the vertices and increment polygon count
    // Get the number of vertices in the current mesh's polygon
    unsigned long polygonVertexCount = meshPolygonsIter.polygonVertexCount();
    if ( polygonVertexCount >= 3 )
    {
#ifdef VALIDATE_DATA
        // Skip over any duplicate vertices in this face.
        // Very rarely, a cunning user manages to corrupt
        // a face entry on the mesh and somehow configure
        // a face to include the same vertex multiple times.
        // This will cause the read-back of this data to
        // reject the face, and can crash other COLLADA
        // consumers, so better to lose the data here
        MIntArray vertexIndices;
        vertexIndices.setLength ( polygonVertexCount );
        for ( int pv = 0; pv < polygonVertexCount; ++pv )
        {
            vertexIndices[pv] = pv;
        }

        for ( uint n = 0; n < vertexIndices.length() - 1; ++n )
        {
            for ( uint m = n + 1; m < vertexIndices.length(); )
            {
                if ( vertexIndices[n] == vertexIndices[m] )
                {
                    vertexIndices.remove ( m );
                }
                else ++m;
            }
        }
        // Get the number of vertices of the current polygon.
        numVertices = vertexIndices.length();
#else
        // Get the number of vertices of the current polygon.
        numVertices = polygonVertexCount;
#endif

        addVertexCount = true;
    }

    return addVertexCount;
}
Beispiel #3
0
void load_from_hds(HDS &hds, MFloatPointArray &points, MIntArray &nFV, MIntArray &F)
{
    size_t nV   = hds.nV();
    size_t nF   = hds.nF();
    size_t nIHE = hds.nIHE();
    
    points.setLength(nV);
    for (size_t k=0; k<nV; k++) 
    {
        points[k](0) = hds.V[3*k+0];
        points[k](1) = hds.V[3*k+1];
        points[k](2) = hds.V[3*k+2];
    }
    
    nFV.setLength(nF);
    for (size_t k=0; k<nF; k++) nFV[k] = hds.nFV[k];
    
    F.setLength(nIHE);
    for (size_t k=0; k<nIHE; k++) F[k] = hds.tip[k];
}
Beispiel #4
0
void create_subdivided_face(int sdRes, int nV, double *uvs, double *itv, int Tidx, MFloatArray &uA, MFloatArray &vA, MIntArray &uvIdx)
{
    HDS hds;
    
    hds.V.setDims(2, nV); memcpy(&hds.V.v[0], uvs, 2*nV*sizeof(double));
    hds.nFV.setDims(1, 1); hds.nFV[0] = nV;

    hds.tip.setDims(1, nV); 
    for (size_t k=0; k<nV; k++) 
    {
        hds.tip[k] = k;
    }
    finalize_HDS(hds);
    
    size_t nHE = hds.nHE(), nIHE = hds.nIHE();⟵
    hds.T.setDims(1, nHE);
    hds.itv.setDims(1, nHE);

    memset(&hds.T.v[0], 0, nHE*sizeof(bool)); if (nV==5) hds.T[Tidx] = 1;
    memcpy(&hds.itv.v[0], itv, nV*sizeof(double));

    // border halfedge tags
    for (size_t k=nIHE; k<nHE; k++) 
    {
        hds.itv[k] = hds.itv[hds.twin[k]];
    }
    
    TCC_MAX::linear_subdivide(hds, sdRes);
    
    int sd_nV = hds.nV();
    int sd_nIHE = hds.nIHE();

    uA.setLength(sd_nV);
    vA.setLength(sd_nV);
    for (int k=0; k<sd_nV; k++)
    {
        uA[k] = hds.V[2*k+0];
        vA[k] = hds.V[2*k+1];
    }
    
    uvIdx.setLength(sd_nIHE);
    for (int k=0; k<sd_nIHE; k++)
    {
        uvIdx[k]=hds.tip[k];
    }
}
Beispiel #5
0
// Propagate objectGroups from inMesh to subdivided outMesh
// Note: Currently only supporting facet groups (for per-facet shading)
MStatus
createSmoothMesh_objectGroups(const MFnMeshData &inMeshDat,
    int subdivisionLevel, MFnMeshData &newMeshDat) {

    MStatus returnStatus;

    int facesPerBaseFace = (int)(pow(4.0f, subdivisionLevel));
    MIntArray newCompElems;

    for(unsigned int gi=0; gi < inMeshDat.objectGroupCount(); gi++) {
        unsigned int compId = inMeshDat.objectGroup(gi, &returnStatus);
        MCHECKERR(returnStatus, "cannot get objectGroup() comp ID.");
        MFn::Type compType = inMeshDat.objectGroupType(compId, &returnStatus);
        MCHECKERR(returnStatus, "cannot get objectGroupType().");

        // get elements from inMesh objectGroupComponent
        MIntArray compElems;
        MFnSingleIndexedComponent compFn(inMeshDat.objectGroupComponent(compId), &returnStatus );
        MCHECKERR(returnStatus, "cannot get MFnSingleIndexedComponent for inMeshDat.objectGroupComponent().");
        compFn.getElements(compElems);

        // Only supporting kMeshPolygonComponent ObjectGroups at this time
        // Skip the other types
        if (compType == MFn::kMeshPolygonComponent) {

            // convert/populate newCompElems from compElems of inMesh
            // (with new face indices) to outMesh
            newCompElems.setLength( compElems.length() * facesPerBaseFace );
            for (unsigned int i=0; i < compElems.length(); i++) {

                int startElemIndex = i * facesPerBaseFace;
                int startElemValue = compElems[i] * facesPerBaseFace;

                for (int j=0; j < facesPerBaseFace; j++) {
                    newCompElems[startElemIndex+j] = startElemValue+j;
                }
            }
            // create comp
            createComp(newMeshDat, compType, compId, newCompElems);
        }
    }
    return MS::kSuccess;
}
double SGIntersectFunction::getShapeIntersectDist(const SGShape& targetShape, const MMatrix& shapeMatrix, const MMatrix& camMatrix)
{
	MPoint mousePoint(SGMouse::x, SGMouse::y, 0);

	MMatrix worldToView = SGMatrix::getWorldToViewMatrix(camMatrix);
	MPointArray points; points.setLength(targetShape.numPoints);
	for (int i = 0; i < targetShape.numPoints; i++) {
		float x = targetShape.points[i * 3 + 0];
		float y = targetShape.points[i * 3 + 1];
		float z = targetShape.points[i * 3 + 2];
		MPoint point(x, y, z);
		points[i] = SGMatrix::getViewPointFromWorld(point * shapeMatrix, camMatrix, &worldToView );
	}

	MIntArray indices; indices.setLength(targetShape.numPoly * targetShape.interval);
	for (int i = 0; i < targetShape.numPoly * targetShape.interval; i++){
		indices[i] = targetShape.indices[i];
	}

	double closeDist = 10000000.0;

	for (int i = 0; i < targetShape.numPoly; i++){
		int index1 = indices[i*3];
		int index2 = indices[i*3+1];
		int index3 = indices[i*3+2];

		double dist1 = SGMatrix::getLineDist(points[index1], points[index2], mousePoint);
		double dist2 = SGMatrix::getLineDist(points[index2], points[index3], mousePoint);
		double dist3 = SGMatrix::getLineDist(points[index3], points[index1], mousePoint);

		if (dist1 < closeDist) 
			closeDist = dist1;
		if (dist2 < closeDist) 
			closeDist = dist2;
		if (dist3 < closeDist)
			closeDist = dist3;
	}
	return closeDist;
}
Beispiel #7
0
void CalculateSampleWeights(const std::map<int, double>& distances, double radius,
                            MIntArray& vertexIds, MDoubleArray& weights) {
  
  std::map<int, double>::const_iterator itDistance;
  std::vector<std::pair<int, double> > samples;
  for (itDistance = distances.begin();
        itDistance != distances.end();
        itDistance++) {
    double x = itDistance->second;
    double w = 1.0 - (x/radius);
    samples.push_back(std::pair<int, double>(itDistance->first, w));
  }

  // Make the samples a multiple of 4 so we can use fast intrinsics!
  int remainder = 4 - ((samples.size()-1) % 4);
  if (remainder != 4) {
    for (int i = 0; i < remainder; ++i) {
      samples.push_back(std::pair<int, double>(0, 0.0));
    }
  }

  unsigned int length = (unsigned int)samples.size();
  weights.setLength(length);
  vertexIds.setLength(length);
  std::sort(samples.begin(), samples.end(), SampleSort);
  std::vector<std::pair<int, double> >::iterator iter;
  int ii = 0;
  double sum = 0.0;
  for (iter = samples.begin(); iter != samples.end(); ++iter, ++ii) {
    vertexIds[ii] = (*iter).first;
    weights[ii] = (*iter).second;
    sum += (*iter).second;
  }
  assert(sum > 0.0);
  // Normalize the weights
  for (unsigned int i = 0; i < weights.length(); ++i) {
    weights[i] /= sum;
  }
}
bool tm_polygon_edgestoring::calculate( MIntArray &edgesArray)
{

	if(!objectIsSet)
	{
		MGlobal::displayError("tm_polygon_edgestoring::calculate - Object is not set.");
		return false;
	}

	MFnMesh meshFn( meshObject);
	MItMeshEdge edgeIt(meshObject);
	MItMeshPolygon faceIt(meshObject);
	unsigned numInputEdges = edgesArray.length();
	int *visitedEdges = new int[numInputEdges];
	for( unsigned e = 0; e < numInputEdges; e++) visitedEdges[e] = 0;
	std::list <int> ringEdgesList;
	int prevIndex;
	MIntArray faces;
	MIntArray edgeFaces;
	MIntArray faceEdges;

	int edgeIndex = edgesArray[0];
	ringEdgesList.push_back( edgeIndex);
	visitedEdges[0] = 1;
	edgeIt.setIndex( edgeIndex, prevIndex);
	edgeIt.getConnectedFaces( faces);
	unsigned numFaces = faces.length();
	unsigned numFaceEdges;
	for( unsigned face = 0; face < numFaces; face++)
	{
		edgeIndex = edgesArray[0];
		int lastFace, newFace;
		if( face == 1)	lastFace = faces[0];
		else			lastFace = -1;

		unsigned COUNTER = 0;
		while( COUNTER < 32000)
		{
		COUNTER++;
			edgeIt.setIndex( edgeIndex, prevIndex);
			edgeIt.getConnectedFaces( edgeFaces);
			if(edgeFaces.length() > 1)
			{
				if( edgeFaces[0] == lastFace)
					newFace = edgeFaces[1];
				else
					newFace = edgeFaces[0];
			}
			else
				newFace = edgeFaces[0];
			faceIt.setIndex( newFace, prevIndex);

			lastFace = newFace;

			bool founded = false;
			for( unsigned e = 0; e < numInputEdges; e++)
			{
				if( edgesArray[e] == edgeIndex) continue;
				if( visitedEdges[e] == 1) continue;
				faceIt.getEdges( faceEdges);
				numFaceEdges = faceEdges.length();
				for( unsigned fe = 0; fe < numFaceEdges; fe++)
				{
					if( faceEdges[fe] == edgesArray[e])
					{
						founded = true;
						edgeIndex = edgesArray[e];
						visitedEdges[e] = 1;
						if( face == 0)
							ringEdgesList.push_front( edgeIndex);
						else
							ringEdgesList.push_back( edgeIndex);
					}
					if( founded) break;
				}
				if( founded) break;
			}
			if(!founded) break;
		}
	}
	if (visitedEdges != NULL) delete [] visitedEdges;

	unsigned numRingEdges = (unsigned)ringEdgesList.size();
	edgesArray.setLength( numRingEdges);
	for( unsigned e = 0; e < numRingEdges; e++)
	{
		edgesArray[e] = *ringEdgesList.begin();
		ringEdgesList.pop_front();
	}
	return true;
}
void ToMayaMeshConverter::addUVSet( MFnMesh &fnMesh, const MIntArray &polygonCounts, IECore::ConstMeshPrimitivePtr mesh, const std::string &sPrimVarName, const std::string &tPrimVarName, const std::string &stIdPrimVarName, MString *uvSetName ) const
{
	IECore::PrimitiveVariableMap::const_iterator sIt = mesh->variables.find( sPrimVarName );
	bool haveS = sIt != mesh->variables.end();
	IECore::PrimitiveVariableMap::const_iterator tIt = mesh->variables.find( tPrimVarName );
	bool haveT = tIt != mesh->variables.end();
	IECore::PrimitiveVariableMap::const_iterator stIdIt = mesh->variables.find( stIdPrimVarName );
	bool haveSTId = stIdIt != mesh->variables.end();

	if ( haveS && haveT )
	{
		if ( sIt->second.interpolation != IECore::PrimitiveVariable::FaceVarying )
		{
			IECore::msg( IECore::Msg::Warning,"ToMayaMeshConverter::doConversion",  boost::format(  "PrimitiveVariable \"%s\" has unsupported interpolation (expected FaceVarying).") % sPrimVarName );
			return;
		}

		if ( tIt->second.interpolation != IECore::PrimitiveVariable::FaceVarying )
		{
			IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", boost::format( "PrimitiveVariable \"%s\" has unsupported interpolation (expected FaceVarying).") % tPrimVarName);
			return;
		}

		if ( !sIt->second.data )
		{
			IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", boost::format( "PrimitiveVariable \"%s\" has no data." ) % sPrimVarName );
		}

		if ( !tIt->second.data )
		{
			IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", boost::format( "PrimitiveVariable \"%s\" has no data." ) % tPrimVarName );
		}

		/// \todo Employ some M*Array converters to simplify this
		int numUVs = mesh->variableSize( IECore::PrimitiveVariable::FaceVarying );

		IECore::ConstFloatVectorDataPtr u = IECore::runTimeCast<const IECore::FloatVectorData>(sIt->second.data);

		if ( !u )
		{
			IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", boost::format( "PrimitiveVariable \"%s\" has unsupported type \"%s\"." ) % sPrimVarName % sIt->second.data->typeName() );
			return;
		}

		assert( (int)u->readable().size() == numUVs );
		
		IECore::ConstFloatVectorDataPtr v = IECore::runTimeCast<const IECore::FloatVectorData>(tIt->second.data);
		if ( !v )
		{
			IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", boost::format( "PrimitiveVariable \"%s\" has unsupported type \"%s\"." ) % tPrimVarName % tIt->second.data->typeName() );
			return;
		}

		assert( (int)v->readable().size() == numUVs );
		
		const std::vector<float> &uAll = u->readable();
		const std::vector<float> &vAll = v->readable();

		if ( uvSetName )
		{
			bool setExists = false;
			MStringArray existingSets;
			fnMesh.getUVSetNames( existingSets );
			for ( unsigned i=0; i < existingSets.length(); ++i )
			{
				if ( *uvSetName == existingSets[i] )
				{
					fnMesh.clearUVs( uvSetName );
					setExists = true;
					break;
				}
			}
			
			if ( !setExists )
			{
				MDagPath dag;
				MStatus s = fnMesh.getPath( dag );
				if ( s )
				{
					fnMesh.createUVSetWithName( *uvSetName );
				}
				else
				{
					fnMesh.createUVSetDataMeshWithName( *uvSetName );
				}
			}
		}
		
		MIntArray uvIds;
		uvIds.setLength( numUVs );
		MFloatArray uArray;
		MFloatArray vArray;
		
		if( haveSTId )
		{
			// Get compressed uv values by matching them with their uvId.
			IECore::ConstIntVectorDataPtr uvId = IECore::runTimeCast<const IECore::IntVectorData>(stIdIt->second.data);
			if ( !uvId )
			{
				IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", boost::format( "PrimitiveVariable \"%s\" has unsupported type \"%s\"." ) % stIdPrimVarName % stIdIt->second.data->typeName() );
				return;
			}
			
			const std::vector<int> &uvIdData = uvId->readable();
	
			assert( (int)uvIdData.size() == numUVs );
			
			int highestId = 0;
			for ( int i = 0; i < numUVs; i++)
			{
				uvIds[i] = uvIdData[i];
				if( uvIdData[i] > highestId )
				{
					highestId = uvIdData[i];
				}
			}
			
			// u and v arrays need only be as long as the number of unique uvIds
			uArray.setLength( highestId + 1 );
			vArray.setLength( highestId + 1 );
			
			for ( int i = 0; i < numUVs; i++ )
			{
				uArray[ uvIds[i] ] = uAll[i];
				// FromMayaMeshConverter does the opposite of this
				vArray[ uvIds[i] ] = 1 - vAll[i];
			}
		}
		else
		{
			// If for some reason we cannot find the uv indices, set the UVs using the old way
			// the performances in maya won't be good (for weigth painting in particular)
			uArray.setLength( numUVs );
			vArray.setLength( numUVs );

			for ( int i = 0; i < numUVs; i++)
			{
				uArray[i] = u->readable()[i];
				// FromMayaMeshConverter does the opposite of this
				vArray[i] = 1 - v->readable()[i];
			}
			
			for ( int i = 0; i < numUVs; i++)
			{
				uvIds[i] = i;
			}
		}
		
		MStatus s = fnMesh.setUVs( uArray, vArray, uvSetName );
		if ( !s )
		{
			IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", "Failed to set UVs." );
			return;
		}

		s = fnMesh.assignUVs( polygonCounts, uvIds, uvSetName );
		if ( !s )
		{
			IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", "Failed to assign UVs." );
			return;
		}

	}
	else if ( haveS )
	{
		IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", boost::format( "Primitive variable \"%s\" found, but not \"%s\"." ) % sPrimVarName % tPrimVarName );
	}
	else if ( haveT )
	{
		IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", boost::format( "Primitive variable \"%s\" found, but not \"%s\"." ) % tPrimVarName % sPrimVarName );
	}
	else
	{
		assert( !uvSetName );
	}
}
bool ToMayaMeshConverter::doConversion( IECore::ConstObjectPtr from, MObject &to, IECore::ConstCompoundObjectPtr operands ) const
{
	MStatus s;

	IECore::ConstMeshPrimitivePtr mesh = IECore::runTimeCast<const IECore::MeshPrimitive>( from );
	assert( mesh );

	if ( !mesh->arePrimitiveVariablesValid() )
	{
		return false;
	}

	MFloatPointArray vertexArray;
	MIntArray polygonCounts;
	MIntArray polygonConnects;

	MFnMesh fnMesh;

	int numVertices = 0;
	IECore::PrimitiveVariableMap::const_iterator it = mesh->variables.find("P");
	if ( it != mesh->variables.end() )
	{
		/// \todo Employ some M*Array converters to simplify this
		IECore::ConstV3fVectorDataPtr p = IECore::runTimeCast<const IECore::V3fVectorData>(it->second.data);
		if (p)
		{
			numVertices = p->readable().size();

			vertexArray.setLength( numVertices );
			for (int i = 0; i < numVertices; i++)
			{
				vertexArray[i] = IECore::convert<MFloatPoint, Imath::V3f>( p->readable()[i] );
			}
		}
		else
		{
			IECore::ConstV3dVectorDataPtr p = IECore::runTimeCast<const IECore::V3dVectorData>(it->second.data);
			if (p)
			{
				numVertices = p->readable().size();

				vertexArray.setLength( numVertices );
				for (int i = 0; i < numVertices; i++)
				{
					vertexArray[i] = IECore::convert<MFloatPoint, Imath::V3d>( p->readable()[i] );
				}
			}
			else
			{
				// "P" is not convertible to an array of "points"
				return false;
			}
		}
	}


	IECore::ConstIntVectorDataPtr verticesPerFace = mesh->verticesPerFace();
	assert( verticesPerFace );
	int numPolygons = verticesPerFace->readable().size();

	polygonCounts.setLength( numPolygons );
	for (int i = 0; i < numPolygons; i++)
	{
		polygonCounts[i] = verticesPerFace->readable()[i];
	}

	IECore::ConstIntVectorDataPtr vertexIds = mesh->vertexIds();
	assert( vertexIds );
	int numPolygonConnects = vertexIds->readable().size();
	polygonConnects.setLength( numPolygonConnects );
	for (int i = 0; i < numPolygonConnects; i++)
	{
		polygonConnects[i] = vertexIds->readable()[i];
	}

	MObject mObj = fnMesh.create( numVertices, numPolygons, vertexArray, polygonCounts, polygonConnects, to, &s );

	if (!s)
	{
		return false;
	}

	it = mesh->variables.find("N");
	if ( it != mesh->variables.end() )
	{
		if (it->second.interpolation == IECore::PrimitiveVariable::FaceVarying )
		{
			/// \todo Employ some M*Array converters to simplify this
			MVectorArray vertexNormalsArray;
			IECore::ConstV3fVectorDataPtr n = IECore::runTimeCast<const IECore::V3fVectorData>(it->second.data);
			if (n)
			{
				int numVertexNormals = n->readable().size();

				vertexNormalsArray.setLength( numVertexNormals );
				for (int i = 0; i < numVertexNormals; i++)
				{
					vertexNormalsArray[i] = IECore::convert<MVector, Imath::V3f>( n->readable()[i] );
				}
			}
			else
			{
				IECore::ConstV3dVectorDataPtr n = IECore::runTimeCast<const IECore::V3dVectorData>(it->second.data);
				if (n)
				{
					int numVertexNormals = n->readable().size();

					vertexNormalsArray.setLength( numVertexNormals );
					for (int i = 0; i < numVertexNormals; i++)
					{
						vertexNormalsArray[i] = IECore::convert<MVector, Imath::V3d>( n->readable()[i] );
					}
				}
				else
				{
					IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", boost::format( "PrimitiveVariable \"N\" has unsupported type \"%s\"." ) % it->second.data->typeName() );
				}
			}
			
			if ( vertexNormalsArray.length() )
			{
				MStatus status;
				MItMeshPolygon itPolygon( mObj, &status );
				if( status != MS::kSuccess )
				{
					IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", "Failed to create mesh iterator" );
				}

				unsigned v = 0;
				MIntArray vertexIds;
				MIntArray faceIds;
				
				for ( ; !itPolygon.isDone(); itPolygon.next() )
				{
					for ( v=0; v < itPolygon.polygonVertexCount(); ++v )
					{
						faceIds.append( itPolygon.index() );
						vertexIds.append( itPolygon.vertexIndex( v ) );
					}
				}

				if( !fnMesh.setFaceVertexNormals( vertexNormalsArray, faceIds, vertexIds ) )
				{
					IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", "Setting normals failed" );
				}
			}
		}
		else
		{
			IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", "PrimitiveVariable \"N\" has unsupported interpolation (expected FaceVarying)." );
		}
	}

	bool haveDefaultUVs = false;
	IECore::PrimitiveVariableMap::const_iterator sIt = mesh->variables.find( "s" );
	IECore::RefCountedPtr sDataRef = ( sIt == mesh->variables.end() ) ? 0 : static_cast<IECore::RefCountedPtr>( sIt->second.data );

	/// Add named UV sets
	std::set< std::string > uvSets;
	for ( it = mesh->variables.begin(); it != mesh->variables.end(); ++it )
	{
		const std::string &sName = it->first;

		size_t suffixOffset = sName.rfind( "_s" );

		if ( ( suffixOffset != std::string::npos) && ( suffixOffset == sName.length() - 2 ) )
		{
			std::string uvSetNameStr = sName.substr( 0, suffixOffset );

			if ( uvSetNameStr.size() )
			{
				MString uvSetName = uvSetNameStr.c_str();
				std::string tName = uvSetNameStr + "_t";
				std::string stIdName = uvSetNameStr + "Indices";

				addUVSet( fnMesh, polygonCounts, mesh, sName, tName, stIdName, &uvSetName );

				uvSets.insert( uvSetNameStr );
				
				if ( sDataRef == static_cast<IECore::RefCountedPtr>( it->second.data ) )
				{
					haveDefaultUVs = true;
				}
			}
		}
	}

	/// Add default UV set if it isn't just a reference to a named set
	if ( !haveDefaultUVs )
	{
		addUVSet( fnMesh, polygonCounts, mesh, "s", "t", "stIndices" );
	}

	// We do the search again, but looking for primvars ending "_t", so we can catch cases where either "UVSETNAME_s" or "UVSETNAME_t" is present, but not both, taking care
	// not to attempt adding any duplicate sets
	for ( it = mesh->variables.begin(); it != mesh->variables.end(); ++it )
	{
		const std::string &tName = it->first;

		size_t suffixOffset = tName.rfind( "_t" );

		if ( ( suffixOffset != std::string::npos) && ( suffixOffset == tName.length() - 2 ) )
		{
			std::string uvSetNameStr = tName.substr( 0, suffixOffset );

			if ( uvSetNameStr.size() && uvSets.find( uvSetNameStr ) == uvSets.end() )
			{
				MString uvSetName = uvSetNameStr.c_str();
				std::string sName = uvSetNameStr + "_s";
				std::string stIdName = uvSetNameStr + "Indices";
				
				addUVSet( fnMesh, polygonCounts, mesh, sName, tName, stIdName, &uvSetName );
				uvSets.insert( uvSetNameStr );
			}
		}
	}

	/// If we're making a mesh node (rather than a mesh data) then make sure it belongs
	/// to the default shading group and add the ieMeshInterpolation attribute.
	MObject oMesh = fnMesh.object();
	if( oMesh.apiType()==MFn::kMesh )
	{
		assignDefaultShadingGroup( oMesh );
		setMeshInterpolationAttribute( oMesh, mesh->interpolation() );
	}

	/// \todo Other primvars, e.g. vertex color ("Cs")

	return true;
}
Beispiel #11
0
bool writeMeshStaticDataInCache(drn_writer_t * cache,
	DRNTDagNode & node,
	drn_scene::MeshContainer * meshContainer,
	DRNTHardEdge & he, MeshExportMode mode)
{
	uint32_t drnStatus = 0;
	MStatus status;
	MFnMesh mesh(node.dagPath);

	if (mode == MESH_EXPORT_FULL_TOPOLOGY)
	{
		meshContainer->numPolygons = mesh.numPolygons(&status);
		meshContainer->numVertices = mesh.numVertices(&status);
		meshContainer->numNormals = mesh.numNormals(&status);
	}
	else
	{
		meshContainer->numPolygons = 0;
		meshContainer->numVertices = 0;
		meshContainer->numNormals = 0;
	}

	MIntArray vertexCount;
	MIntArray vertexList;
	MIntArray normalCount;
	MIntArray normalList;
	MIntArray uvCounts;
	MIntArray uvIds;
	mesh.getAssignedUVs(uvCounts, uvIds);
	MIntArray triangleCount;
	MIntArray triangleList;
	MIntArray triangleNList;
	MIntArray triangleUVList;
	mesh.getVertices(vertexCount, vertexList);
	mesh.getNormalIds(normalCount, normalList);
	mesh.getTriangles(triangleCount, triangleList);
	triangleNList.setLength(triangleList.length());
	triangleUVList.setLength(triangleList.length());
	meshContainer->numTriangles = triangleList.length()  / 3;
	int * vcarray = new int[vertexCount.length()];
	int * vlarray = new int[vertexList.length()];
	int * ncarray = new int[normalCount.length()];
	int * nlarray = new int[normalList.length()];
	// Triangulation
	int poly_idx_offset = 0;
	int tri_idx_offset = 0;
	for (int i = 0; i < mesh.numPolygons(); ++i)
	{
		for (int j = 0; j < triangleCount[i]; ++j)
		{
			for(unsigned int k=0; k < 3; ++k)
			{
				int v_idx = triangleList[tri_idx_offset+j*3 + k];
				int match = -1;
				int l = 0;
				while (match < 0 && l < vertexCount[i])
				{
					if (vertexList[poly_idx_offset+l] == v_idx)
					match = l;
					++l;
				}
				triangleNList[tri_idx_offset+j*3 + k] = normalList[poly_idx_offset+match];
				int id = 0;
				if (uvIds.length() != 0)
				mesh.getPolygonUVid(i, match, id);
				triangleUVList[tri_idx_offset+j*3 + k] = id;
			}
		}
		poly_idx_offset += vertexCount[i];
		tri_idx_offset += 3 * triangleCount[i];
	}
	he.tlist.resize(triangleList.length(), -1);
	//he.itlist.resize(triangleList.length());
	he.itlist.resize(triangleList.length());
	//std::map<std::pair<int, int>, int> h;
	std::map<triplet, int> h;
	int idx = 0;
	for (int i = 0, n = triangleList.length(); i != n; ++i)
	{
		//std::pair<int, int> p = std::make_pair(triangleList[i], triangleNList[i]);
		triplet p(triangleList[i], triangleNList[i], triangleUVList[i]);
		//std::map<std::pair<int, int>, int>::const_iterator match = h.find(p);
		std::map<triplet, int>::const_iterator match = h.find(p);
		if (match != h.end())
		{
			he.tlist[i] = match->second;
			he.itlist[i] = match->first;
		}
		else
		{
			h[p] = idx;
			he.tlist[i] = idx;
			he.itlist[i] = p;
			++idx;
		}
	}
	meshContainer->numHwVertices = he.idmax = idx;
	if (mode == MESH_EXPORT_FULL_TOPOLOGY)
	{
		vertexCount.get(vcarray);
		vertexList.get(vlarray);
		normalCount.get(ncarray);
		normalList.get(nlarray);
		drnStatus = drn_writer_add_chunk(cache, vcarray, sizeof(int) * vertexCount.length());
		meshContainer->vertexCountPerFace = drn_writer_get_last_chunk_id(cache);
		drnStatus = drn_writer_add_chunk(cache, vlarray, sizeof(int) * vertexList.length());
		meshContainer->vertexListPerFace = drn_writer_get_last_chunk_id(cache);
		drnStatus = drn_writer_add_chunk(cache, ncarray, sizeof(int) * normalCount.length());
		meshContainer->normalCountPerFace = drn_writer_get_last_chunk_id(cache);
		drnStatus = drn_writer_add_chunk(cache, nlarray, sizeof(int) * normalList.length());
		meshContainer->normalListPerFace = drn_writer_get_last_chunk_id(cache);
		drnStatus = drn_writer_add_chunk(cache, & (he.tlist[0]), sizeof(int) * he.tlist.size());
		meshContainer->triangleList = drn_writer_get_last_chunk_id(cache);
		delete[] vcarray;
		delete[] vlarray;
		delete[] ncarray;
		delete[] nlarray;
	}
	else
	{
		meshContainer->numUVSets = 0;
		drnStatus = drn_writer_add_chunk(cache, & (he.tlist[0]), sizeof(int) * he.tlist.size());
		meshContainer->triangleList = drn_writer_get_last_chunk_id(cache);
		meshContainer->defaultUVSet = 0;
	}
	DRNT_DBG_LVL2(std::cout << "trianglelist" << triangleList << std::endl;);
Beispiel #12
0
// Propagate objectGroups from inMesh to subdivided outMesh
// Note: Currently only supporting facet groups (for per-facet shading)
MStatus
createSmoothMesh_objectGroups( MFnMesh const & inMeshFn,
    MFnMeshData const & inMeshDat, MFnMeshData &newMeshDat, int level, int numSubfaces ) {

    MStatus status;

    MIntArray newCompElems;

    std::vector<unsigned int> offsets; // mapping of offsets for subdivided faces

    for(unsigned int gi=0; gi<inMeshDat.objectGroupCount(); gi++) {

        unsigned int compId = inMeshDat.objectGroup(gi, &status);
        MCHECKERR(status, "cannot get objectGroup() comp ID.");

        MFn::Type compType = inMeshDat.objectGroupType(compId, &status);
        MCHECKERR(status, "cannot get objectGroupType().");

        // Only supporting kMeshPolygonComponent ObjectGroups at this time
        // Skip the other types
        if (compType == MFn::kMeshPolygonComponent) {

            // get elements from inMesh objectGroupComponent
            MIntArray compElems;
            MFnSingleIndexedComponent compFn(
                inMeshDat.objectGroupComponent(compId), &status );
            MCHECKERR(status, "cannot get MFnSingleIndexedComponent for inMeshDat.objectGroupComponent().");
            compFn.getElements(compElems);

            if (compElems.length()==0) {
                continue;
            }

            // over-allocation to maximum possible length
            newCompElems.setLength( numSubfaces );

            if (offsets.empty()) {
                // lazy population of the subface offsets table
                int nfaces = inMeshFn.numPolygons();

                offsets.resize(nfaces);

                for (int i=0, count=0; i<nfaces; ++i) {

                    int nverts = inMeshFn.polygonVertexCount(i),
                        nsubfaces = computeNumSubfaces(nverts, level);

                    offsets[i] = count;
                    count+=nsubfaces;
                }
            }

            unsigned int idx = 0;

            // convert/populate newCompElems from compElems of inMesh
            // (with new face indices) to outMesh
            for (unsigned int i=0; i < compElems.length(); i++) {

                int nverts = inMeshFn.polygonVertexCount(compElems[i]),
                    nsubfaces = computeNumSubfaces(nverts, level);

                unsigned int subFaceOffset = offsets[compElems[i]];

                for (int j=0; j<nsubfaces; ++j) {
                    newCompElems[idx++] = subFaceOffset++;
                }
            }

            // resize to actual length
            newCompElems.setLength( idx );

            // create comp
            createComp(newMeshDat, compType, compId, newCompElems);
        }
    }
    return MS::kSuccess;
}
Beispiel #13
0
//--------------------------------------------------------------------------------------
void		componentConverter::vtxToConnectedFaceVtx(const	MIntArray&		vtxIDs, 
															MIntArray&		outVtxIDs)	
//--------------------------------------------------------------------------------------
{
	// Wandelt die vtxSelection in die connecteten faceVtx um (die Vertizen der verbundenen Faces)
	// Die gegebenen Vtx werden nicht mit hinzugefuegt

	outVtxIDs.setLength(0);
	outVtxIDs.setSizeIncrement(vtxIDs.length() / 4);

	MItMeshVertex	vertIter(mesh);
	MItMeshPolygon	polyIter(mesh);

	BPT_BA			allFaces(polyIter.count(), true);
	BPT_BA			allVtx(vertIter.count(), true);	// BA mit den vtxIDs initialisieren

	// Die vtxIds bereits jetzt false setzen
	allVtx.setBits(vtxIDs, false);


	MIntArray		conFaces;		// hlt die verbundenen Faces
	MIntArray		conVtx;			// Im face enthaltene Vtx
	
	uint i, x, y , l2,l3, l = vtxIDs.length();
	
	
	for(i = 0; i < l; i++)
	{
		vertIter .setIndex(vtxIDs[i], tmp);
		
		vertIter.getConnectedFaces(conFaces);
		
		// Jetzt die gueltigen conFaces holen
		conFaces = allFaces & conFaces;
		
		// Jetzt die conFaces false setzen, danit diese nicht wieder  bearbeitet werden
		allFaces.setBits(conFaces, false);
		
		
		l2 = conFaces.length();
		
		// jetzt die restlichen Faces on the fly in Vtx umwandeln
		for(x = 0; x < l2; x++)
		{
			
			// Jetzt die vertizen des Faces holen und auf Array packen, wenn sie einzigartig sind
			polyIter.setIndex(conFaces[x], tmp);
			
			polyIter.getVertices(conVtx);
			
			// Checken, ob Vtx einzigartig sind
			conVtx = allVtx & conVtx;

			// Das was uebrig bleibt im BitArray deaktivieren und zum outArray hinzufuegen 
			allVtx.setBits(conVtx, false);


			l3 = conVtx.length();
			for(y = 0; y < l3; y++)
			{
				outVtxIDs.append(conVtx[y]);
			}
		}
				
	}
	
}
MStatus genRod(
	const MPoint &p0,
	const MPoint &p1,
	const double radius,
	const unsigned int nSegs,
	
	int &nPolys,
	MPointArray &verts,
	MIntArray &polyCounts,
	MIntArray &polyConnects
)
{
	verts.clear();
	polyCounts.clear();
	polyConnects.clear();
	
	unsigned int nCirclePts = nSegs; 
	unsigned int nVerts = 2 * nCirclePts;
	
	// Calculate the local axiis of the rod
	MVector vec( p1 - p0 );
	MVector up( 0.0, 1.0, 0.0 );
	MVector xAxis, yAxis, zAxis;
	
	yAxis = vec.normal();
	if( up.isParallel( yAxis, 0.1 ) )
		up = MVector( 1.0, 0.0, 0.0 );
	xAxis = yAxis ^ up;
	zAxis = (xAxis ^ yAxis).normal();
	xAxis = (yAxis ^ zAxis ).normal(); 
	
	// Calculate the vertex positions
	verts.setLength( nVerts );
	double angleIncr = 2.0 * M_PI / nSegs;
	double angle;
	MPoint p;
	double x, z;
	unsigned int i;
	for( i=0, angle=0; i < nCirclePts; i++, angle += angleIncr )
	{
		// Calculate position in circle
		x = radius * cos( angle );
		z = radius * sin( angle );
		
		p = p0 + x * xAxis + z * zAxis;

		verts[ i ] = p;
		
		p += vec;

		verts[ i + nCirclePts ] = p;
	}
	
	nPolys = nSegs;
	
	// Generate polycounts
	polyCounts.setLength( nPolys );
	for( i=0; i < polyCounts.length(); i++ )
		polyCounts[i] = 4;
	
	// Generate polyconnects
	polyConnects.setLength( nPolys * 4 );
	polyConnects.clear();
	for( i=0; i < nSegs; i++ )
	{
		polyConnects.append( linearIndex( 0, i, 2, nCirclePts ) );
		polyConnects.append( linearIndex( 0, i+1, 2, nCirclePts ) );
		polyConnects.append( linearIndex( 1, i+1, 2, nCirclePts ) );
		polyConnects.append( linearIndex( 1, i, 2, nCirclePts ) );
	}
		
	return MS::kSuccess;
}
Beispiel #15
0
//
// Change the UVS for the given selection on this mesh object.
//
///////////////////////////////////////////////////////////////////////////////
MStatus flipUVCmd::getTweakedUVs(
    const MObject & meshObj,					// Object
    MIntArray & uvList,						// UVs to move
    MFloatArray & uPos,						// Moved UVs
    MFloatArray & vPos )					// Moved UVs
{
    MStatus status;
    unsigned int i;
    MFloatArray uArray;
    MFloatArray vArray;

    MFnMesh mesh( meshObj );

    // Read all UVs from the poly object
    status = mesh.getUVs(uArray, vArray);
    CHECK_MSTATUS_AND_RETURN_IT(status);

    unsigned int nbUvShells = 1;
    MIntArray uvShellIds;
    if ((!flipGlobal) || extendToShell)
    {
        // First, extract the UV shells.
        status = mesh.getUvShellsIds(uvShellIds, nbUvShells);
        CHECK_MSTATUS_AND_RETURN_IT(status);
    }

    if (extendToShell)
    {
        // Find all shells that have at least a selected UV.
        bool *selected = new bool[nbUvShells];
        for (i = 0 ; i<nbUvShells ; i++)
            selected[i] = false;

        for (i = 0 ; i<uvList.length() ; i++)
        {
            int indx = uvList[i];
            selected[uvShellIds[indx]] = true;
        }

        // Now recompute a new list of UVs to modify.

        unsigned int numUvs = mesh.numUVs();
        unsigned int numSelUvs = 0;

        // Preallocate a buffer, large enough to hold all Ids. This
        // prevents multiple reallocation from happening when growing
        // the array.
        uvList.setLength(numUvs);

        for (i = 0 ; i<numUvs ; i++)
        {
            if (selected[uvShellIds[i]])
                uvList[numSelUvs++] = i;
        }

        // clamp the array to the proper size.
        uvList.setLength(numSelUvs);

        delete [] selected;
    }

    // For global flips, just pretend there is only one shell
    if (flipGlobal) nbUvShells = 1;

    float *minMax = new float[nbUvShells*4];

    for (i = 0 ; i<nbUvShells ; i++)
    {
        minMax[4*i+0] =  1e30F;				// Min U
        minMax[4*i+1] =  1e30F;				// Min V
        minMax[4*i+2] = -1e30F;				// Max U
        minMax[4*i+3] = -1e30F;				// Max V
    }

    // Get the bounding box of the UVs, for each shell if flipGlobal
    // is true, or for the whole selection if false.
    for (i = 0 ; i<uvList.length() ; i++)
    {
        int indx = uvList[i];
        int shellId = 0;
        if (!flipGlobal) shellId = uvShellIds[indx];

        if (uArray[indx] < minMax[4*shellId+0])
            minMax[4*shellId+0] = uArray[indx];
        if (vArray[indx] < minMax[4*shellId+1])
            minMax[4*shellId+1] = vArray[indx];
        if (uArray[indx] > minMax[4*shellId+2])
            minMax[4*shellId+2] = uArray[indx];
        if (vArray[indx] > minMax[4*shellId+3])
            minMax[4*shellId+3] = vArray[indx];
    }

    // Adjust the size of the output arrays
    uPos.setLength(uvList.length());
    vPos.setLength(uvList.length());

    for (i = 0 ; i<uvList.length() ; i++)
    {
        int shellId = 0;
        int indx = uvList[i];
        if (!flipGlobal) shellId = uvShellIds[indx];

        // Flip U or V along the bounding box center.
        if (horizontal)
        {
            uPos[i] = minMax[4*shellId+0] + minMax[4*shellId+2] -
                      uArray[indx];
            vPos[i] = vArray[indx];
        }
        else
        {
            uPos[i] = uArray[indx];
            vPos[i] = minMax[4*shellId+1] + minMax[4*shellId+3] -
                      vArray[indx];
        }
    }

    delete [] minMax;

    return MS::kSuccess;
}
Beispiel #16
0
//-------------------------------------------------------------------------------------------
void	vertexFty::doIt()
//-------------------------------------------------------------------------------------------
{
	meshCreator& creator = *ftyCreator;
	MIntArray& vtxList = *selVtxIDs;
	BPT_Helpers helper;

	//MERKE:Diese prozedur arbeitet nur mit dem MeshCreator, benutzt also kein MFnMesh etc.

	//zuersteinmal ein Ba aufbauen mit den gewählten vertizen
	BPT_BA selCheckList(vtxList,true,false,creator.getLastVtxID());	//ArbeitsArray für die folgende Prozedur
//	BPT_BA selList = selCheckList;									//wird als lookup verwendet, der nicht verändert wird

	//Die einfachste Lösung: Ba aufbauen mit allen Faces, die schon bearbeitet wurden - bedeutet aber auch, dass für jeden SelVtx die 
	//verbundenen Faces geholt werden müssen - momentan ist die Sache ziemlich billig (CPU ZEIT)
	//man müsste zuerst die verbundenen Faces zu allen Vertizen holen, und dese Dann abarbeiten

	MIntArray allConnectedFaces;
	UINT r = null;
	

	UINT l,i,x;				//für iterationen
//	UINT cv;				// == currentVtx

	MIntArray	faceVtx;	//vertizen des jeweiligen faces
	MIntArray	connectedFaces;	//hält die mit dem Vtx verbundenen Faces
	MIntArray	match;			//Array fr übereinstimmende Vtx
	//jetzt durch die SelVtx parsen und eine Facezurodnung herstellen
	l = vtxList.length();

	//alle verbundenen Faces holen
	for(i = null; i < l; i++)
	{

		creator.getConnectedFaces(vtxList[i],connectedFaces);
		
		allConnectedFaces.setLength(allConnectedFaces.length() + connectedFaces.length());


		for(x = null; x < connectedFaces.length(); x++)
		{
			allConnectedFaces[r++] = connectedFaces[x];
		}

	}

	helper.memoryPrune(allConnectedFaces);

	l = allConnectedFaces.length();
	for(i = null; i < l; i++)
	{

		creator.getFaceVtxIDs(allConnectedFaces[i],faceVtx);

		selCheckList.findMatching(faceVtx, match);

		if(match.length() > 1)
			splitFace(faceVtx,match,allConnectedFaces[i]);


	}
	
	/*
	for(i = 0; i < l; i++)
	{
		cv = vtxList[i];
		//wenn der gegenwärtige Vtx noch nicht bearbeitet wurde
		if( ! selCheckList[cv])	//hier lieber operator [] nehmen, da isFlagSet noch nen unnötigen rangecheck macht
		{
			continue;
		}

		//ansonsten weitermachen und:
		//die verbundenen Faces holen
		creator.getConnectedFaces(cv,connectedFaces);

		//jetzt in jedem verbundenen Face checken, ob von den entsprechenden faceVertices
		//gewählte vertices vorhanden sind
		//zuvor aber den gegenwärtigen cv entfernen
		selCheckList.setBitFalse(cv);

		for(x = 0; x < connectedFaces.length(); x++)
		{
			creator.getFaceVtxIDs(connectedFaces[x],faceVtx);

			//wenn mehr als nur der cv auf dem face gewählt sind, dann connectProzedur starten
			selList.findMatching(faceVtx, match);

			//if(match.length() > 1)
			if(match.length() > 1)	//nur testweise
			{//es handelt sich um ein gültiges face, da mindestens 2 vertizen im Face gewählt waren ->splitten
				INVIS(helper.printArray(faceVtx," = zu bearbeitendes Face"););

				splitFace(faceVtx, match, connectedFaces[x]);
				
				//zuguterletzt noch die matches aus selCheckList entfernen, damit diese nicht nochmal bearbeitet werden
		
				selCheckList.remove(match);	
			}
			
		}

	}
*/
}
MStatus DDConvexHullUtils::generateMayaHull(MObject &output,
                                const MPointArray &vertices,
                                const DDConvexHullUtils::hullOpts &hullOptions)
{
    // Allocate and push the vert list into the new array Mem Cleanup req.
    uint numInputVerts = vertices.length();
    double *inputVerts = new double[numInputVerts*3];
    for (uint i=0; i < numInputVerts; i++)
    {
        uint offset = i*3;
        inputVerts[offset]   = vertices[i].x;
        inputVerts[offset+1] = vertices[i].y;
        inputVerts[offset+2] = vertices[i].z;
    }
    
    // Setup the flags
    uint hullFlags = QF_DEFAULT;
    if (hullOptions.forceTriangles)
    {
        hullFlags |= QF_TRIANGLES;
    }
    if (hullOptions.useSkinWidth)
    {
        hullFlags |= QF_SKIN_WIDTH;
    }
    if (hullOptions.reverseTriangleOrder)
    {
        hullFlags |= QF_REVERSE_ORDER;
    }
    
    // Create the description
    HullDesc hullDescription;
    hullDescription.mFlags = hullFlags;
    hullDescription.mMaxVertices = hullOptions.maxOutputVertices;
    hullDescription.mSkinWidth = hullOptions.skinWidth;
    hullDescription.mNormalEpsilon = hullOptions.normalEpsilon;
    hullDescription.mVertexStride = sizeof(double)*3;
    hullDescription.mVcount = numInputVerts;
    hullDescription.mVertices = inputVerts;
    
    // Create the hull
    HullLibrary hullComputer;
    HullResult hullResult;
    HullError err = hullComputer.CreateConvexHull(hullDescription, hullResult);
    MStatus hullStat = MStatus::kSuccess;
    if (err == QE_OK)
    {
        // Grab the verts
        MPointArray outPoints;
        for (uint i=0; i < hullResult.mNumOutputVertices; i++)
        {
            uint offset = i*3;
            MPoint curPoint(hullResult.mOutputVertices[offset],
                            hullResult.mOutputVertices[offset+1],
                            hullResult.mOutputVertices[offset+2]);
            outPoints.append(curPoint);
        }
        
        // Check if the results are in polygons, or triangles. Depending on
        // which for the result is in, the way the face indices are setup
        // is different.
        MIntArray polyCounts;
        MIntArray vertexConnects;
        
        if (hullResult.mPolygons)
        {
            const uint *idx = hullResult.mIndices;
            for (uint i=0; i < hullResult.mNumFaces; i++)
            {
                uint pCount = *idx++;
                polyCounts.append(pCount);
                
                for (uint j=0; j < pCount; j++)
                {
                    uint val = idx[0];
                    vertexConnects.append(val);
                    idx++;
                }
            }
        }
        else
        {
            polyCounts.setLength(hullResult.mNumFaces);
            for (uint i=0; i < hullResult.mNumFaces; i++)
            {
                
                polyCounts[i] = 3;
                uint *idx = &hullResult.mIndices[i*3];
                
                vertexConnects.append(idx[0]);
                vertexConnects.append(idx[1]);
                vertexConnects.append(idx[2]);
            }
        }
        // Setup the outmesh
        MFnMesh outMeshFn(output);
        outMeshFn.create(hullResult.mNumOutputVertices,
                         hullResult.mNumFaces,
                         outPoints,
                         polyCounts,
                         vertexConnects,
                         output,
                         &hullStat);
    }
    else
    {
        hullStat = MStatus::kFailure;
    }
    
    // Mem Cleanup
    hullComputer.ReleaseResult(hullResult);
    delete[] inputVerts;
    
    return hullStat;
}
Beispiel #18
0
MStatus PtexUVNode::compute( const MPlug &plug, MDataBlock &data )
{
	MStatus stat;
	bool hasNoEffect = false;
	
	MDataHandle inMeshHnd = data.inputValue( inMesh );
	MDataHandle outMeshHnd = data.outputValue( outMesh );
	 
	MDataHandle stateHnd = data.inputValue( state );
	int state = stateHnd.asInt();

	if( state == 1 ) // No Effect/Pass through
		hasNoEffect = true;
		
	if( !hasNoEffect && plug == outMesh )
	{
	    MObject inMeshData = inMeshHnd.asMesh();
				
		if( !hasNoEffect )
		{
			MFnMeshData meshDataFn;
			MObject newMeshData = meshDataFn.create();
			MFnMesh inMeshFn( inMeshData );
			inMeshFn.copy( inMeshData, newMeshData );
			
			MFnMesh meshFn( newMeshData );
			MPointArray pts;
			meshFn.getPoints( pts );

			MStringArray uvSetNames;
			meshFn.getUVSetNames( uvSetNames );
			unsigned int defaultUvSetCount = (unsigned int)uvSetNames.length();

			int num_faces = meshFn.numPolygons();

			MIntArray uvCounts;
			uvCounts.setLength( num_faces );

			for ( int i_f = 0; i_f < num_faces; i_f++ )
			{
				int deg = meshFn.polygonVertexCount( i_f );
				uvCounts[ i_f ] = deg;

				if ( deg != 4 )
				{
					return MS::kFailure;
				}
			}

			MIntArray uvIds;
			uvIds.setLength( 4 * num_faces );

			if ( defaultUvSetCount == 1 )
			{
				int currentUVCount = meshFn.numUVs( uvSetNames[0] );

				MFloatArray us, vs; 
				us.setLength( 4 * num_faces ); 
				vs.setLength( 4 * num_faces );

				for ( int i_f = 0; i_f < num_faces; i_f++ )
				{
					float f = (float)i_f;

					uvIds[ 4 * i_f + 0 ] = 4 * i_f + 0;
					uvIds[ 4 * i_f + 1 ] = 4 * i_f + 1;
					uvIds[ 4 * i_f + 2 ] = 4 * i_f + 2;
					uvIds[ 4 * i_f + 3 ] = 4 * i_f + 3;

					us[ 4 * i_f + 0 ] = (float)i_f;         vs[ 4 * i_f + 0 ] = 0.0f;
					us[ 4 * i_f + 1 ] = (float)i_f + 1.0f;  vs[ 4 * i_f + 1 ] = 0.0f;
					us[ 4 * i_f + 2 ] = (float)i_f + 1.0f;  vs[ 4 * i_f + 2 ] = 1.0f;
					us[ 4 * i_f + 3 ] = (float)i_f;         vs[ 4 * i_f + 3 ] = 1.0f;
				}

				stat = meshFn.setUVs( us, vs, &uvSetNames[0] );
				stat = meshFn.assignUVs( uvCounts, uvIds, &uvSetNames[0] );
			}

			meshFn.updateSurface();
			meshFn.syncObject();

			outMeshHnd.set( newMeshData );
		}	
	}
	else 
		return MS::kUnknownParameter;

	if( hasNoEffect )
		outMeshHnd.set( inMeshHnd.asMesh() );
	
	data.setClean( plug );

	return stat;
}
Beispiel #19
0
bool tm_polyExtract::extractFaces_Func( MSelectionList &selectionList, MStringArray &node_names)
{
	MStatus status;
	MObject meshObj;
	status = selectionList.getDependNode( 0, meshObj);
	if(!status){MGlobal::displayError("tm_polyExtract::extractFaces_Func:   Can't find object !");return false;}
	MFnMesh meshFn( meshObj, &status);
	if(!status){MGlobal::displayError("tm_polyExtract::extractFaces_Func:   Non mesh object founded !");return false;}

	MDagPath meshDagPath_first, meshDagPath;
	selectionList.getDagPath( 0, meshDagPath_first);
	MObject multiFaceComponent;
	MIntArray inputFacesArray;
	inputFacesArray.clear();
	inputFacesArray.setSizeIncrement( 4096);
	MFnComponentListData compListFn;
	compListFn.create();
	for (MItSelectionList faceComponentIter(selectionList, MFn::kMeshPolygonComponent); !faceComponentIter.isDone(); faceComponentIter.next())
	{
		faceComponentIter.getDagPath(meshDagPath, multiFaceComponent);
		if(!(meshDagPath_first == meshDagPath))
		{
			MGlobal::displayError("tm_polyExtract::extractFaces_Func:   Different meshes faces founded !");
			return false;
		}
		if (!multiFaceComponent.isNull())
		{
			for (MItMeshPolygon faceIter(meshDagPath, multiFaceComponent); !faceIter.isDone(); faceIter.next())
			{
				int faceIndex = faceIter.index();
#ifdef _DEBUG
				infoMStr += faceIndex;
				infoMStr += " ";
#endif
				inputFacesArray.append( faceIndex);
				compListFn.add( multiFaceComponent );
			}
		}
	}
	if( inputFacesArray.length() == 0)
	{
		MGlobal::displayError("tm_polyExtract::extractFaces_Func:   No faces founded !");
		return false;
	}
#ifdef _DEBUG
	MGlobal::displayInfo( infoMStr);
#endif

	meshFn.setObject( meshDagPath_first);
	meshObj = meshFn.object();

//	MDagModifier dagModifier;
	MFnDagNode meshDagNodeFn;
	MFnDependencyNode depNodeFn;
	meshDagNodeFn.setObject( meshDagPath_first);
	MString meshName = meshDagNodeFn.name();
	MObject outMesh_attrObject = meshDagNodeFn.attribute( "outMesh");

// ----------------------------------- duplicate shape

	MObject duplicated_meshObjectA;
	MObject duplicated_meshObjectB;
	MObject inMesh_attrObjectA;
	MObject inMesh_attrObjectB;
/*
	MStringArray commandResult;
	MSelectionList selList;

	MGlobal::executeCommand( "duplicate " + meshDagNodeFn.name(), commandResult, 1, 1);
	selList.add( commandResult[0]);
	selList.getDependNode( 0, duplicated_meshObjectA);
	meshDagNodeFn.setObject( duplicated_meshObjectA);
	meshDagNodeFn.setName( meshName + "_tA");
	duplicated_meshObjectA = meshDagNodeFn.child(0);
	meshDagNodeFn.setObject( duplicated_meshObjectA);
	meshDagNodeFn.setName( meshName + "_sA");
	inMesh_attrObjectA = meshDagNodeFn.attribute( "inMesh");

	meshDagNodeFn.setObject( meshDagPath_first);
	selList.clear();

	MGlobal::executeCommand( "duplicate " + meshDagNodeFn.name(), commandResult, 1, 1);
	selList.add( commandResult[0]);
	selList.getDependNode( 0, duplicated_meshObjectB);
	meshDagNodeFn.setObject( duplicated_meshObjectB);
	meshDagNodeFn.setName( meshName + "_tB");
	duplicated_meshObjectB = meshDagNodeFn.child(0);
	meshDagNodeFn.setObject( duplicated_meshObjectB);
	meshDagNodeFn.setName( meshName + "_sB");
	inMesh_attrObjectB = meshDagNodeFn.attribute( "inMesh");
*/
	duplicated_meshObjectA = meshDagNodeFn.duplicate();
	meshDagNodeFn.setObject( duplicated_meshObjectA);
	meshDagNodeFn.setName( meshName + "_tA");
	duplicated_meshObjectA = meshDagNodeFn.child(0);
	meshDagNodeFn.setObject( duplicated_meshObjectA);
	meshDagNodeFn.setName( meshName + "_sA");
	inMesh_attrObjectA = meshDagNodeFn.attribute( "inMesh");

	meshDagNodeFn.setObject( meshDagPath_first);

	duplicated_meshObjectB = meshDagNodeFn.duplicate();
	meshDagNodeFn.setObject( duplicated_meshObjectB);
	meshDagNodeFn.setName( meshName + "_tB");
	duplicated_meshObjectB = meshDagNodeFn.child(0);
	meshDagNodeFn.setObject( duplicated_meshObjectB);
	meshDagNodeFn.setName( meshName + "_sB");
	inMesh_attrObjectB = meshDagNodeFn.attribute( "inMesh");

// ----------------------------------- create node deleteComponent

	MDGModifier dgModifier;

	MObject deleteComponent_nodeObjectA = dgModifier.createNode( MString("deleteComponent"));
	depNodeFn.setObject( deleteComponent_nodeObjectA );
	MObject deleteComponent_attrObjectA( depNodeFn.attribute( "deleteComponents" ));
	MObject inputGeometry_attrObjectA( depNodeFn.attribute( "inputGeometry" ));
	MObject outputGeometry_attrObjectA( depNodeFn.attribute( "outputGeometry" ));
	dgModifier.doIt();
	depNodeFn.setName( "dfA_" + meshName);
	node_names.append( depNodeFn.name());

	MObject deleteComponent_nodeObjectB = dgModifier.createNode( MString("deleteComponent"));
	depNodeFn.setObject( deleteComponent_nodeObjectB );
	MObject deleteComponent_attrObjectB( depNodeFn.attribute( "deleteComponents" ));
	MObject inputGeometry_attrObjectB( depNodeFn.attribute( "inputGeometry" ));
	MObject outputGeometry_attrObjectB( depNodeFn.attribute( "outputGeometry" ));
	dgModifier.doIt();
	depNodeFn.setName( "dfB_" + meshName);
	node_names.append( depNodeFn.name());

// ----------------------------------- set attribute deleteComponent.deleteComponents

	MObject componentList_object = compListFn.object();

	MPlug deleteComponents_plugA( deleteComponent_nodeObjectA, deleteComponent_attrObjectA );
	status = deleteComponents_plugA.setValue( componentList_object );

	MIntArray invertedFaces;
	int numPolygons = meshFn.numPolygons();
	invertedFaces.setLength( numPolygons - inputFacesArray.length());
	int selFace = 0;
	int invFace = 0;
	for( int f = 0; f < numPolygons; f++)
	{
		if( f == inputFacesArray[selFace])
			selFace++;
		else
			invertedFaces[invFace++] = f;
	}
	MFnSingleIndexedComponent singleIndexedComponentFn( meshObj);
	singleIndexedComponentFn.create( MFn::kMeshPolygonComponent);
	singleIndexedComponentFn.addElements( invertedFaces);
	compListFn.clear();
	compListFn.create();
   componentList_object = singleIndexedComponentFn.object();
	compListFn.add( componentList_object);
	componentList_object = compListFn.object();
	MPlug deleteComponents_plugB( deleteComponent_nodeObjectB, deleteComponent_attrObjectB );
	status = deleteComponents_plugB.setValue( componentList_object );

// ------------------------------------- connecting plugs
/**/
	dgModifier.connect(
			meshObj, outMesh_attrObject,
			deleteComponent_nodeObjectA, inputGeometry_attrObjectA
		);
	dgModifier.connect(
			deleteComponent_nodeObjectA, outputGeometry_attrObjectA,
			duplicated_meshObjectA, inMesh_attrObjectA
		);

	dgModifier.connect(
			meshObj, outMesh_attrObject,
			deleteComponent_nodeObjectB, inputGeometry_attrObjectB
		);
	dgModifier.connect(
			deleteComponent_nodeObjectB, outputGeometry_attrObjectB,
			duplicated_meshObjectB, inMesh_attrObjectB
		);

	dgModifier.doIt();

// ---------------------------------- assigning shading group
/**/
	meshDagNodeFn.setObject( meshDagPath_first);
	MObject instObjGroups_attrObject = meshDagNodeFn.attribute( "instObjGroups");
	MPlug instObjGroups_plug( meshObj, instObjGroups_attrObject);
	instObjGroups_plug = instObjGroups_plug.elementByPhysicalIndex(0);
	MPlugArray instObjGroups_plug_connectionsArray;
	instObjGroups_plug.connectedTo( instObjGroups_plug_connectionsArray, false, true);
	if( instObjGroups_plug_connectionsArray.length() > 0)
	{
		MPlug dagSetMembers_plug = instObjGroups_plug_connectionsArray[0];
		MObject shadingSetNode_object = dagSetMembers_plug.node();
		MFnSet setFn( shadingSetNode_object);
		setFn.addMember( duplicated_meshObjectA);
		setFn.addMember( duplicated_meshObjectB);
//depNodeFn.setObject(shadingSetNode_object);
//MGlobal::displayInfo( depNodeFn.name());
	}

// ------------------------------------------------------------
	return true;
}
Beispiel #20
0
void createUVset(TCCData &tccData, int sdRes, MFloatArray &uArray, MFloatArray &vArray, MFloatArray &sc_uArray, MFloatArray &sc_vArray, MIntArray &uvIdx, float lineThickness)
{
    MFloatArray u4, v4, u5T0, v5T0, u5T1, v5T1, u5T2, v5T2, u5T3, v5T3, u5T4, v5T4;
    MIntArray id4, id5T0, id5T1, id5T2, id5T3, id5T4;
    
    double hds4_uvs[]   = { 0,1, 1,1, 1,0, 0,0 },       hds4_itv[] = {1,1,1,1};       create_subdivided_face(sdRes, 4, hds4_uvs, hds4_itv, -1, u4, v4, id4);
    double hds5T0_uvs[] = { 0,.5, 0,1, 1,1, 1,0, 0,0 }, hds5T0_itv[] = {.5,.5,1,1,1}; create_subdivided_face(sdRes, 5, hds5T0_uvs, hds5T0_itv, 0, u5T0, v5T0, id5T0);
    double hds5T1_uvs[] = { 0,0, 0,.5, 0,1, 1,1, 1,0 }, hds5T1_itv[] = {1,.5,.5,1,1}; create_subdivided_face(sdRes, 5, hds5T1_uvs, hds5T1_itv, 1, u5T1, v5T1, id5T1);
    double hds5T2_uvs[] = { 1,0, 0,0, 0,.5, 0,1, 1,1 }, hds5T2_itv[] = {1,1,.5,.5,1}; create_subdivided_face(sdRes, 5, hds5T2_uvs, hds5T2_itv, 2, u5T2, v5T2, id5T2);
    double hds5T3_uvs[] = { 1,1, 1,0, 0,0, 0,.5, 0,1 }, hds5T3_itv[] = {1,1,1,.5,.5}; create_subdivided_face(sdRes, 5, hds5T3_uvs, hds5T3_itv, 3, u5T3, v5T3, id5T3);
    double hds5T4_uvs[] = { 0,1, 1,1, 1,0, 0,0, 0,.5 }, hds5T4_itv[] = {.5,1,1,1,.5}; create_subdivided_face(sdRes, 5, hds5T4_uvs, hds5T4_itv, 4, u5T4, v5T4, id5T4);
    
    
    int nV4 = u4.length(), nHE4 = id4.length();
    int nV5 = u5T0.length(), nHE5 = id5T0.length();
    
    int nF = tccData.nFV.length();

    int nHE = 0, nV = 0;
    for (int kF = 0; kF<nF; kF++)
    {
        switch (tccData.nFV[kF])
        {
            case 4: nV+=nV4; nHE+=nHE4; break;
            case 5: nV+=nV5; nHE+=nHE5; break;
        }
    }
    
    uArray.setLength(nV); sc_uArray.setLength(nV);
    vArray.setLength(nV); sc_vArray.setLength(nV);
    uvIdx.setLength(nHE);
    
    int kHE = 0, sd_kV = 0, sd_kHE = 0;
    for (int kF = 0; kF<nF; kF++)
    {
        int faceConfig = tccData.nFV[kF];

        if (faceConfig==5)
        {
            for (int kT=0; kT<5; kT++)
            {
                if (tccData.T[kHE+kT]) break;
                faceConfig++;
            }
        }

        // uScale and vScale are chosen to not use T-edges, but match the U/V directions of the patch (convention: first edge gets vScale)
        switch (faceConfig)
        {
            case 4: copy_patch_uvs(sd_kV, sd_kHE, u4, v4, id4, uArray, vArray, tccData.itv[kHE], tccData.itv[kHE+1], sc_uArray, sc_vArray, uvIdx, lineThickness); break;
            case 5: copy_patch_uvs(sd_kV, sd_kHE, u5T0, v5T0, id5T0, uArray, vArray, tccData.itv[kHE+3], tccData.itv[kHE+4], sc_uArray, sc_vArray, uvIdx, lineThickness); break;
            case 6: copy_patch_uvs(sd_kV, sd_kHE, u5T1, v5T1, id5T1, uArray, vArray, tccData.itv[kHE+4], tccData.itv[kHE], sc_uArray, sc_vArray, uvIdx, lineThickness); break;
            case 7: copy_patch_uvs(sd_kV, sd_kHE, u5T2, v5T2, id5T2, uArray, vArray, tccData.itv[kHE], tccData.itv[kHE+1], sc_uArray, sc_vArray, uvIdx, lineThickness); break;
            case 8: copy_patch_uvs(sd_kV, sd_kHE, u5T3, v5T3, id5T3, uArray, vArray, tccData.itv[kHE+1], tccData.itv[kHE+2], sc_uArray, sc_vArray, uvIdx, lineThickness); break;
            case 9: copy_patch_uvs(sd_kV, sd_kHE, u5T4, v5T4, id5T4, uArray, vArray, tccData.itv[kHE+2], tccData.itv[kHE+3], sc_uArray, sc_vArray, uvIdx, lineThickness); break;
        }
        
        
        kHE += tccData.nFV[kF];
    }
}
// --------------------------------------------------------
void GeometryPolygonExporter::retrieveVertexIndices (
    MIntArray &vertexIndices,
    MItMeshPolygon &meshPolygonsIter,
    uint &numPolygons,
    uint &numVertices )
{
    // Get the number of vertices in the current mesh's polygon
    int polygonVertexCount = meshPolygonsIter.polygonVertexCount();
    if ( triangulated && polygonVertexCount > 3 )
    {
        int numTriangles;
        meshPolygonsIter.numTriangles ( numTriangles );
        if ( numTriangles > 0 )
        {
            numVertices = 3;
            MPointArray vertexPositions;
            MIntArray meshVertexIndices;
            meshPolygonsIter.getTriangles ( vertexPositions, meshVertexIndices );
            vertexIndices.setLength ( meshVertexIndices.length() );
            numPolygons = meshVertexIndices.length() / numVertices;

            // Map the vertex indices to iterator vertex indices so that we can
            // get information from the iterator about normals and such.
            uint meshVertexIndexCount = meshVertexIndices.length();
            for ( uint mvi = 0; mvi < meshVertexIndexCount; ++mvi )
            {
                int meshVertexIndex = meshVertexIndices[mvi];
                int polygonVertexCount = meshPolygonsIter.polygonVertexCount();
                int iteratorVertexIndex = 0;
                for ( int pv = 0; pv < polygonVertexCount; ++pv )
                {
                    if ( ( int ) meshPolygonsIter.vertexIndex ( pv ) == meshVertexIndex )
                    {
                        iteratorVertexIndex = pv;
                    }
                }
                vertexIndices[mvi] = iteratorVertexIndex;
            }
        }
        else numPolygons = 0;
    }
    else if ( polygonVertexCount >= 3 )
    {
        numPolygons = 1;
        vertexIndices.setLength ( polygonVertexCount );
        for ( int pv = 0; pv < polygonVertexCount; ++pv )
        {
            vertexIndices[pv] = pv;
        }

#ifdef VALIDATE_DATA
        // Skip over any duplicate vertices in this face.
        // Very rarely, a cunning user manages to corrupt
        // a face entry on the mesh and somehow configure
        // a face to include the same vertex multiple times.
        // This will cause the read-back of this data to
        // reject the face, and can crash other COLLADA
        // consumers, so better to lose the data here
        for ( uint n = 0; n < vertexIndices.length() - 1; ++n )            {
            for ( uint m = n + 1; m < vertexIndices.length(); )
            {
                if ( vertexIndices[n] == vertexIndices[m] )
                {
                    vertexIndices.remove ( m );
                }
                else ++m;
            }
        }
        // Get the number of vertices of the current polygon.
        numVertices = vertexIndices->length();
#else
        // Get the number of vertices of the current polygon.
        numVertices = polygonVertexCount;
#endif
    }
}
Beispiel #22
0
MStatus updateTCCData::compute_remap(TCCData &tccData, MIntArray &vR, MIntArray &pO, MIntArray &cS)
{
    pair<multimap<int, int>::iterator,multimap<int, int>::iterator> fRange;
    multimap<int, int> dst_V2F; // maps smallest face vertex index to all its faces
    
    MIntArray &src_nFV(tccData.nFV), &dst_nFV(tccData.o_nFV);
    MIntArray &src_F(tccData.F),     &dst_F(tccData.o_F);
    
    // get source and destination F and nFV arrays
    size_t src_nHE = src_F.length(), src_nF = src_nFV.length();
    size_t dst_nHE = dst_F.length(), dst_nF = dst_nFV.length();
    
    pO.setLength(src_nF);
    cS.setLength(src_nF);
    
    MIntArray dst_F2H(dst_nF, 0);
    MIntArray dst_cS(dst_nF, 0);
    
    // build lookup map
    size_t kHE = 0;
    for (size_t kF=0; kF<dst_nF; kF++)
    {
        dst_F2H[kF] = kHE;
        size_t cnFV = dst_nFV[kF];
        size_t minVI = dst_nHE;     // big enough...
        size_t ccS = 0;
        for (size_t kFV=0; kFV<cnFV; kFV++)
        {
            if (dst_F[kHE]<minVI) 
            { 
                minVI = dst_F[kHE];
                ccS = kFV;
            }
            kHE++;
        }
        dst_V2F.insert(pair<int,int>(minVI, kF));
        dst_cS[kF] = ccS;
    }
    
    size_t src_F2H = 0;
    
    // look up new faces in old mesh
    for (size_t kF=0; kF<src_nF; kF++)
    {
        size_t cnFV = src_nFV[kF];
        
        // find minimum remapped vtx index, remap vertices
        size_t minVI = src_nHE;     // start with smth big enough...
        size_t src_ccS = 0;
        bool newFace = false;
        for (size_t kFV=0; kFV<cnFV; kFV++)
        {
            int vRI = vR[src_F[src_F2H+kFV]];
            
            if (vRI == NO_DST_VTXID) { newFace = true; break; }
            if (vRI < minVI) {
                minVI = vRI;
                src_ccS = kFV;
            }
        }
        

        // no new vertices? ok, then let's see if we can find this face in dst
        if (!newFace)
        {
            bool faceMismatch = true;
            
            fRange = dst_V2F.equal_range(minVI);
            for (multimap<int, int>::iterator it=fRange.first; it!=fRange.second; ++it)
            {
                int dst_rF = (*it).second; // remapped face candidate
                if (dst_nFV[dst_rF] != cnFV) continue; // face vertex count mismatch -> not the right face
                
                faceMismatch = false;
                
                size_t ccS = dst_cS[dst_rF] + cnFV - src_ccS; // additional cnFV makes ccS always positive.
                
                for (size_t kFV=0; kFV<cnFV; kFV++)
                {
                    // index in dst polygon, starting with the same vertex offset (relative to smallest index) as src polygon
                    size_t o_kHE = dst_F2H[dst_rF] + ((kFV + ccS) % cnFV);
                    
                    int src_vI = vR[ src_F[ src_F2H + kFV ] ];
                    int dst_vI = dst_F[ o_kHE ];
                    
                    if ( src_vI != dst_vI ) { faceMismatch = true; break; }
                }
                if (!faceMismatch) {
                    pO[kF] = dst_rF;
                    cS[kF] = ccS;
                    break;
                }
            }
            
            if (faceMismatch) newFace = true;
        }
        
        // if new face, add it to delta_F and delta_nFV
        if (newFace)
        {
            pO[kF] = NO_DST_VTXID;
        }
        
        src_F2H += cnFV;
    }
    
    return MS::kSuccess;
}
MStatus genBall( 
	const MPoint &centre,
	const double radius,
	const unsigned int nSegs,
	
	int &nPolys,
	MPointArray &verts,
	MIntArray &polyCounts,
	MIntArray &polyConnects
)	
{
	verts.clear();
	polyCounts.clear();
	polyConnects.clear();
	
	int nAzimuthSegs = nSegs * 2;
	int nZenithSegs = nSegs;
	
	int nAzimuthPts = nAzimuthSegs; // Last point corresponds to the first
	int nZenithPts = nZenithSegs + 1; // Last point is at other pole
	
	
	double azimIncr = 2.0 * M_PI / nAzimuthSegs;
	double zenIncr = M_PI / nZenithSegs;
	
	MPoint p;
	double azimuth, zenith;
	double sinZenith;
	int azi, zeni;
	
	zenith = 0.0;
	for( zeni=0; zeni < nZenithPts; zeni++, zenith += zenIncr )
	{
		azimuth = 0.0;
		for( azi=0; azi < nAzimuthPts; azi++, azimuth += azimIncr )
		{
			sinZenith = sin(zenith);
			
			p.x = radius * sinZenith * cos(azimuth);
			p.y = radius * cos(zenith);
			p.z = radius * sinZenith * sin(azimuth);
		
			verts.append( p );
		}
	}
	
	// Calculate the number of polygons
	nPolys = nAzimuthSegs * nZenithSegs;
	
	// Each face has four points
	polyCounts.setLength( nPolys );
	int i;
	for( i=0; i < nPolys; i++ )
		polyCounts[i] = 4;
	
	// Generate the faces
	for( zeni=0; zeni < nZenithSegs; zeni++ )
	{
		for( azi=0; azi < nAzimuthSegs; azi++ )
		{
			//MGlobal::displayInfo( MString( "\n" ) + azi + "," + zeni );
			
			polyConnects.append( linearIndex( zeni, azi, nZenithPts, nAzimuthPts ) );
			polyConnects.append( linearIndex( zeni, azi+1, nZenithPts, nAzimuthPts ) );
			polyConnects.append( linearIndex( zeni+1, azi+1, nZenithPts, nAzimuthPts ) );
			polyConnects.append( linearIndex( zeni+1, azi, nZenithPts, nAzimuthPts ) );
		}
	}	
	
	return MS::kSuccess;
}
void
VertexPolyColourCommand::PrepareMesh(VertexColourJob& job)
{
	MDGModifier* modifier = NULL;

	// If the mesh doesn't have any vertex colours yet, create some default ones
#if (MAYA_API_VERSION > 650)
	bool hasVertexColours = true;
	if (0 == job.meshData->mesh->numColorSets())
	{
		hasVertexColours = false;
	}
	else
	{
		// Check the color set isn't the VCP_MasterComp used by the layers system
		if (job.meshData->mesh->numColorSets() == 1 && job.meshData->hasLayers)
		{
			hasVertexColours = false;
		}
	}

	if (!hasVertexColours)
	{
		if (m_isUndoable)
			modifier = new MDGModifier;

		// Create a colour set
		MString colorSetName("colorSet1");
		job.meshData->mesh->createColorSet(colorSetName, modifier);
		job.meshData->mesh->setCurrentColorSetName(colorSetName, modifier);

		// Create default vertex colours
		MIntArray vertList;
		MColorArray colors;
		unsigned int numVerts = (unsigned int)job.meshData->mesh->numVertices();
		vertList.setLength(numVerts);
		colors.setLength(numVerts);
		unsigned int i = 0;
		for (i = 0; i < numVerts; i++)
			vertList[i] = i;
		for (i = 0; i < numVerts; i++)
			colors[i].set(MColor::kRGB, 0.37f, 0.37f, 0.37f, 1.0f);		// default rgb is default 0.37

		// Fill vertex colours
		job.meshData->mesh->setVertexColors(colors, vertList, modifier);

		// If the mesh has layer data, set the active layer
		if (job.meshData->hasLayers)
		{
			MString name("colorSet1");

			MFnDagNode attribNode(job.meshData->mesh->parent(0));
			MObject activeLayerObj = attribNode.attribute(MString("VCP_Layer_Active"));
			if (!activeLayerObj.isNull())
			{
				MPlug activeLayerPlug(attribNode.object(), activeLayerObj);
				activeLayerPlug.setValue(name);
			}

			MString command = "VCP_Layer_CreateDefaultLayerAttribs " + attribNode.fullPathName() + " colorSet1";
			MGlobal::executeCommand(command);
			MGlobal::executeCommand("VCP_Layers_UpdateUI();");
/*
			
			attribNode.addAttribute(attr);
			MObject layerBlendAmountObj = attribNode.attribute(MString("VCP_Layer_") + name + "_BlendAmount");
			if (!layerBlendAmountObj.isNull())
			{
				MPlug layerBlendAmountPlug(attribNode.object(), layerBlendAmountObj);
				layerBlendAmountPlug.setValue(100.0f);
			}

			MObject layerBlendModeObj = attribNode.attribute(MString("VCP_Layer_") + name + "_BlendMode");
			if (!layerBlendModeObj.isNull())
			{
				MPlug layerBlendModePlug(attribNode.object(), layerBlendModeObj);
				layerBlendModePlug.setValue("Replace");
			}

			MObject layerVisibleObj = attribNode.attribute(MString("VCP_Layer_") + name + "_Visible");
			if (!layerVisibleObj.isNull())
			{
				MPlug layerVisiblePlug(attribNode.object(), layerVisibleObj);
				layerVisiblePlug.setValue(true);
			}*/

			job.meshData->DeleteLayersData();
			GatherLayersData();
		}
	}
#endif

	if (modifier != NULL)
	{
		m_undos.push_back(modifier);
	}
}
Beispiel #25
0
bool tm_polygon_selectloop::calculate( MIntArray &edgesArray, const int &selIndex, const int &mode, const double &angle_deg, const int &maxCount)
{
	if(!objectIsSet)
	{
		MGlobal::displayError("tm_polygon_selectloop::calculate - Object is not set.");
		return false;
	}

	double angle = angle_deg*M_PI/180;
	MStatus stat;
	pMesh = new MFnMesh( meshObject, &stat);				if (!stat) return false;
	int meshEdgesCount = pMesh->numEdges( &stat);		if (!stat) return false;
	int *pVisitedEdges = new int[meshEdgesCount];
	for( int i = 0; i < meshEdgesCount; i++) pVisitedEdges[i] = 0;

	pVtxIt = new MItMeshVertex( meshObject, &stat);			if (!stat) return false;
	pEdgeIt = new MItMeshEdge( meshObject, &stat);			if (!stat) return false;
	pFaceIt = new MItMeshPolygon( meshObject, &stat);		if (!stat) return false;

	int edgeVtx[2];
	int edge, vtx;
	stat = pMesh->getEdgeVertices( selIndex, edgeVtx);	if (!stat) return false;
	std::list <int> edgesList;
	edgesList.push_front( selIndex);

	int count = 1;
	edge = selIndex;
	pVisitedEdges[selIndex] = 1;
	vtx = edgeVtx[0];
	while( findNextEdge( edge, vtx, mode, angle))
	{
		if (pVisitedEdges[edge]) break;
		if ((++count) > maxCount) break;
		edgesList.push_front( edge);
		pVisitedEdges[edge] = 1;
	}
	edge = selIndex;
	vtx = edgeVtx[1];
	while( findNextEdge( edge, vtx, mode, angle))
	{
		if (pVisitedEdges[edge]) break;
		if ((++count) > maxCount) break;
		edgesList.push_back( edge);
		pVisitedEdges[edge] = 1;
	}

	int len = (int)edgesList.size();
	edgesArray.setLength( len);
	for( int i = 0; i < len; i++)
	{
		edgesArray[i] = *edgesList.begin();
		edgesList.pop_front();
	}

	if( pMesh != NULL) delete pMesh;
	if( pVtxIt != NULL) delete pVtxIt;
	if( pEdgeIt != NULL) delete pEdgeIt;
	if( pFaceIt != NULL) delete pFaceIt;
	if( pVisitedEdges != NULL) delete [] pVisitedEdges;

	return true;
}