Exemple #1
0
/*!
* \return	void
* \ingroup	AlgRank
* \brief	Performs the minimum of sorting on an array of values
*		such that the n'th value in the array has rank n. That
*		is all values before the n'th are less than or equal to
*		it and all values after the n'th are greater than or equal
*		to it.
* \param	elm			Array of values.
* \param	nElm			Number of values.
* \param	elmSz			Size of each value.
* \param	rank			Required rank in the range
*					[0 - (nElm - 1)].
* \param	buf			A pointer to a single value to
*					be used as a workspace.
* \param	compFn			A value comparison function in
*					the same form as qsort(3).
*/
void		AlgRankSelectV(void *elm, int nElm, unsigned int elmSz,
                           int rank, void *buf,
                           int (*compFn)(void *, void *))
{
    int		id0,
            id1,
            id2,
            id3,
            idR;
    char 		*elmP,
                *tst;

    if(rank < 0)
    {
        rank = 0;
    }
    else if(rank >= nElm)
    {
        rank = nElm - 1;
    }
    id2 = 0;
    id3 = elmSz * (nElm - 1);
    idR = elmSz * rank;
    tst = (char *)buf;
    elmP = (char *)elm;
    while(id2 < id3)
    {
        AlgRankElmCopy(tst, elmP + idR, elmSz);
        id0 = id2;
        id1 = id3;
        do
        {
            while(compFn(elmP + id0, tst) < 0)
            {
                id0 += elmSz;
            }
            while(compFn(tst, elmP + id1) < 0)
            {
                id1 -= elmSz;
            }
            if(id0 <= id1)
            {
                AlgRankElmSwap(elmP + id0, elmP + id1, elmSz);
                id0 += elmSz;
                id1 -= elmSz;
            }
        } while(id0 <= id1);
        if(id1 < idR)
        {
            id2 = id0;
        }
        if(idR < id0)
        {
            id3 = id1;
        }
    }
}
Exemple #2
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;
}
Exemple #3
0
MStatus tm_polySlot::doIt( const MArgList& )
//
//	Description:
//		implements the MEL tm_polySlot command.
//
//	Arguments:
//		args - the argument list that was passes to the command from MEL
//
//	Return Value:
//		MS::kSuccess - command succeeded
//		MS::kFailure - command failed (returning this value will cause the 
//                     MEL script that is being run to terminate unless the
//                     error is caught using a "catch" statement.
//
{
#ifdef _DEBUG
cout << endl << "####################################################" << endl;
cout << "tm_polySlot::doIt - DEBUG version info:" << endl;
#endif
	MStatus status;

	// Parse the selection list for objects with selected UV components.
	// To simplify things, we only take the first object that we find with
	// selected UVs and operate on that object alone.
	//
	// All other objects are ignored and return warning messages indicating
	// this limitation.
	//
	MGlobal::getActiveSelectionList( oldSelList );
	MItSelectionList selListIter( oldSelList );
	selListIter.setFilter( MFn::kMesh );

	// The tm_polySlot node only accepts a component list input, so we build
	// a component list using MFnComponentListData.
	//
	// MIntArrays could also be passed into the node to represent the edgesIds,
	// but are less storage efficient than component lists, since consecutive 
	// components are bundled into a single entry in component lists.
	//
	MFnComponentListData compListFn;
	compListFn.create();
	bool found = false;
	bool foundMultiple = false;

	for( ; !selListIter.isDone(); selListIter.next() )
	{
		MDagPath dagPath;
		MObject component;
		selListIter.getDagPath( dagPath, component );

		// Check for selected UV components
		//
		if( component.apiType() == MFn::kMeshEdgeComponent )
		{
			if( !found )
			{
				// The variable 'component' holds all selected components on the selected
				// object, thus only a single call to MFnComponentListData::add() is needed
				// to store the selected components for a given object.
				//
				compListFn.add( component );

				// Copy the component list created by MFnComponentListData into our local
				// component list MObject member.
				//
				fComponentList = compListFn.object();

				// Locally store the actual edgesIds of the selected Edges so that this command
				// can directly modify the mesh in the case when there is no history and
				// history is turned off.
				//
				MFnSingleIndexedComponent compFn( component );
				compFn.getElements( fSelEdges );

				// Ensure that this DAG path will point to the shape of our object.
				// Set the DAG path for the polyModifierCmd.
				//
				dagPath.extendToShape();
				setMeshNode( dagPath );
				found = true;
			}
			else
			{
				// Break once we have found a multiple object holding selected UVs, since
				// we are not interested in how many multiple objects there are, only
				// the fact that there are multiple objects.
				//
				foundMultiple = true;
				break;
			}
		}
	}
	if( foundMultiple )
	{
		displayWarning("Found more than one object with selected Edges - Only operating on first found object.");
	}
	if( !found )
	{
		displayError( "tm_polySlot command failed: Unable to find selected edges" );
		return MStatus::kFailure;
	}
	// Initialize the polyModifierCmd node type - mesh node already set
	//
	setModifierNodeType( tm_polySlotNode::id );
//##################################################################
	alwaysWithConstructionHistory = true;
	status = doModifyPoly();
	if( !status){displayError( "tm_polySlot command failed!" );return status;}
//################################################################## get polymodifier node name and select it
	getModifierNodeName();
	newSelList.add( modifierNodeName);
	MGlobal::setActiveSelectionList( newSelList);//, MGlobal::kAddToList);
//##################################################################
	successResult();

	return MStatus::kSuccess;
}
Exemple #4
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;
}
Exemple #5
0
MStatus tm_polySplit::doIt( const MArgList& args)
{
#ifdef _DEBUG
cout << endl << "####################################################" << endl;
cout << "tm_polySplit::doIt - DEBUG version info:" << endl;
#endif
	MStatus status;

	MGlobal::getActiveSelectionList( oldSelList );

	MArgDatabase argData( syntax(), args);

	//parse flags
	//
	if(argData.isFlagSet( loop_Flag))
	{
		cmd_flag_loop = true;
		argData.getFlagArgument( loop_Flag, 0, cmd_flag_loop_mode);
		argData.getFlagArgument( loop_Flag, 1, cmd_flag_loop_angle);
//		argData.getFlagArgument( loop_Flag, 2, cmd_flag_loop_maxcount); // - max count;
	}
	else if(argData.isFlagSet( sel_Flag))
	{
		cmd_flag_loop = false;
		cmd_flag_sel = true;
	}


	MSelectionList selectionList;
	argData.getObjects( selectionList);
	MItSelectionList selListIter( selectionList );
	selListIter.setFilter( MFn::kMesh );

	// The tm_polySplit node only accepts a component list input, so we build
	// a component list using MFnComponentListData.
	//
	// MIntArrays could also be passed into the node to represent the edgesIds,
	// but are less storage efficient than component lists, since consecutive 
	// components are bundled into a single entry in component lists.
	//
	MFnComponentListData compListFn;
	compListFn.create();
	bool found = false;
	bool foundMultiple = false;
	MObject meshObj;

	for( ; !selListIter.isDone(); selListIter.next() )
	{
		MDagPath dagPath;
		MObject component;
		selListIter.getDagPath( dagPath, component );
		meshObj = dagPath.node();

		// Check for selected Edges components
		//
		if( component.apiType() == MFn::kMeshEdgeComponent )
		{
			if( !found )
			{
				// The variable 'component' holds all selected components on the selected
				// object, thus only a single call to MFnComponentListData::add() is needed
				// to store the selected components for a given object.
				//
				compListFn.add( component );

				// Copy the component list created by MFnComponentListData into our local
				// component list MObject member.
				//
				fComponentList = compListFn.object();

				// Locally store the actual edgesIds of the selected Edges so that this command
				// can directly modify the mesh in the case when there is no history and
				// history is turned off.
				//
				MFnSingleIndexedComponent compFn( component );
				compFn.getElements( fSelEdges );

				// Ensure that this DAG path will point to the shape of our object.
				// Set the DAG path for the polyModifierCmd.
				//
				dagPath.extendToShape();
				setMeshNode( dagPath );
				found = true;
			}
			else
			{
				// Break once we have found a multiple object holding selected UVs, since
				// we are not interested in how many multiple objects there are, only
				// the fact that there are multiple objects.
				//
				foundMultiple = true;
				break;
			}
		}
	}
#ifdef _DEBUG
cout << endl << "########################## checking arguments:" << endl;
cout << endl << "fSelEdges = ";for(unsigned i=0;i<fSelEdges.length();i++) cout << fSelEdges[i] << " ";cout << endl;
#endif
	if( foundMultiple )
	{
		displayWarning("Found more than one object with selected Edges - Only operating on first found object.");
	}
	if( !found )
	{
		displayError( "tm_polySplit command failed: Unable to find selected edges" );
		return MStatus::kFailure;
	}
	// Initialize the polyModifierCmd node type - mesh node already set
	//
	setModifierNodeType( tm_polySplitNode::id );
//##################################################################
	alwaysWithConstructionHistory = true;
	status = doModifyPoly();
	if( !status){displayError( "tm_polySplit command failed!" );return status;}
//################################################################## get polymodifier node name and select it
	getModifierNodeName();
	newSelList.add( modifierNodeName);
	MGlobal::setActiveSelectionList( newSelList);//, MGlobal::kAddToList);
//##################################################################
	setResult( modifierNodeName);

	return MStatus::kSuccess;
/*
cout<<endl<<"**********"<<endl;return MStatus::kSuccess;
*/
}
MStatus DDConvexHullUtils::componentToVertexIDs(MIntArray &outIndices,
                                                const MObject &mesh,
                                                const MObject &component)
{
    // Create the funciton sets
    MFnSingleIndexedComponent compFn(component);
    MFnMesh meshFn(mesh);
        
    MIntArray elems;
    compFn.getElements(elems);
    uint elemLen = elems.length();
    
    // Convert the components to vertices based on component type
    uint compType = compFn.componentType();
    if (compType == MFn::kMeshVertComponent)
    {
        outIndices = elems;
    }
    else if (compType == MFn::kMeshEdgeComponent)
    {
        for (uint i=0; i < elemLen; i++)
        {
            int2 edgeVerts;
            meshFn.getEdgeVertices(elems[i], edgeVerts);
            outIndices.append(edgeVerts[0]);
            outIndices.append(edgeVerts[1]);
        }
    }
    else if (compType == MFn::kMeshPolygonComponent)
    {
        for (uint i=0; i < elemLen; i++)
        {
            // Grab verts for the current poly
            MIntArray polyVerts;
            meshFn.getPolygonVertices(elems[i], polyVerts);
            uint polyVertsLen = polyVerts.length();
            for (uint j=0; j < polyVertsLen; j++)
            {
                outIndices.append(polyVerts[j]);
            }
        }
    }
    else if (compType == MFn::kMeshFaceVertComponent)
    {
        // I think this is how you convert face to object
        // relative vertices...
        MIntArray faceCounts;
        MIntArray faceVerts;
        meshFn.getVertices(faceCounts, faceVerts);
        for (uint j=0; j < elemLen; j++)
        {
            outIndices.append(faceVerts[j]);
        }
    }
    else
    {
        // Not supported
        return MStatus::kNotImplemented;
    }
    return MStatus::kSuccess;
}
Exemple #7
0
MStatus meshOp::doIt( const MArgList& argList )
//
//	Description:
//		implements the MEL meshOp command.
//
//	Arguments:
//		argList - the argument list that was passes to the command from MEL
//
//	Return Value:
//		MS::kSuccess - command succeeded
//		MS::kFailure - command failed (returning this value will cause the 
//                     MEL script that is being run to terminate unless the
//                     error is caught using a "catch" statement.
//
{
	MStatus status;
	bool badArgument = false;

	// Only one parameter is expected to be passed to this command: the mesh
	// operation type. Get it, validate it or stop prematurely
	//
	if (argList.length() == 1)
	{
		int operationTypeArgument = argList.asInt(0);
		if (operationTypeArgument < 0
			|| operationTypeArgument > kMeshOperationCount - 1)
		{
			badArgument = true;
		}
		else
		{
			fOperation = (MeshOperation)operationTypeArgument;
		}
	}
	else badArgument = true;

	if (badArgument)
	{
		cerr << "Expecting one parameter: the operation type." << endl;
		cerr << "Valid types are: " << endl;
		cerr << "   0 - Subdivide edge(s)." << endl;
		cerr << "   1 - Subdivide face(s)." << endl;
		cerr << "   2 - Extrude edge(s)." << endl;
		cerr << "   3 - Extrude face(s)." << endl;
		cerr << "   4 - Collapse edge(s)." << endl;
		cerr << "   5 - Collapse face(s)." << endl;
		cerr << "   6 - Duplicate face(s)." << endl;
		cerr << "   7 - Extract face(s)." << endl;
		cerr << "   8 - Split face(s)." << endl;
		cerr << "   8 - Chamfer vertex(s)." << endl;
		displayError(" Expecting one parameter: the operation type.");
		return MS::kFailure;
	}

	// Each mesh operation only supports one type of components
	// 
	MFn::Type componentType = meshOpFty::getExpectedComponentType(fOperation);

	// Parse the selection list for selected components of the right type.
	// To simplify things, we only take the first object that we find with
	// selected components and operate on that object alone.
	//
	// All other objects are ignored and return warning messages indicating
	// this limitation.
	//
	MSelectionList selList;
	MGlobal::getActiveSelectionList( selList );
	MItSelectionList selListIter( selList );
	selListIter.setFilter( MFn::kMesh );

	// The meshOperation node only accepts a component list input, so we build
	// a component list using MFnComponentListData.
	//
	// MIntArrays could also be passed into the node to represent the ids,
	// but are less storage efficient than component lists, since consecutive 
	// components are bundled into a single entry in component lists.
	//
	MFnComponentListData compListFn;
	compListFn.create();
	bool found = false;
	bool foundMultiple = false;

	for( ; !selListIter.isDone(); selListIter.next() )
	{
		MDagPath dagPath;
		MObject component;
		selListIter.getDagPath( dagPath, component );

		// Check for selected components of the right type
		//
		if( component.apiType() == componentType )
		{
			if( !found )
			{
				// The variable 'component' holds all selected components 
				// on the selected object, thus only a single call to 
				// MFnComponentListData::add() is needed to store the selected
				// components for a given object.
				//
				compListFn.add( component );

				// Copy the component list created by MFnComponentListData
				// into our local component list MObject member.
				//
				fComponentList = compListFn.object();

				// Locally store the actual ids of the selected components so 
				// that this command can directly modify the mesh in the case 
				// when there is no history and history is turned off.
				//
				MFnSingleIndexedComponent compFn( component );

				// Ensure that this DAG path will point to the shape 
				// of our object. Set the DAG path for the polyModifierCmd.
				//
				dagPath.extendToShape();
				setMeshNode( dagPath );
				found = true;
			}
			else
			{
				// Break once we have found a multiple object holding 
				// selected components, since we are not interested in how 
				// many multiple objects there are, only the fact that there
				// are multiple objects.
				//
				foundMultiple = true;
				break;
			}
		}
	}
	if( foundMultiple )
	{
		displayWarning("Found more than one object with selected components.");
		displayWarning("Only operating on first found object.");
	}

	// Initialize the polyModifierCmd node type - mesh node already set
	//
	setModifierNodeType( meshOpNode::id );

	if( found )
	{
		// Now, pass control over to the polyModifierCmd::doModifyPoly() method
		// to handle the operation.
		//
		status = doModifyPoly();
		
		if( status == MS::kSuccess )
		{
			setResult( "meshOp command succeeded!" );
		}
		else
		{
			displayError( "meshOp command failed!" );
		}
	}
	else
	{
		displayError(
			"meshOp command failed: Unable to find selected components" );
		status = MS::kFailure;
	}
	
	return status;
}
Exemple #8
0
MStatus	grabUVContext::doPress ( MEvent & event, MHWRender::MUIDrawManager& drawMgr, const MHWRender::MFrameContext& context)
{
	if ( event.mouseButton() != MEvent::kLeftMouse || 
		!event.isModifierNone() )
		return MS::kFailure;

	fInStroke = true;

	MPxTexContext::doPress(event, drawMgr, context);

	short x, y;
	event.getPosition( x, y );
	fCurrentScreenPoint = MPoint( x, y );
	fLastScreenPoint = MPoint( x, y );
	fBrushCenterScreenPoint = MPoint( x, y );

	double xView, yView;
	portToView(x, y, xView, yView);	// pos at viewrect coordinate  

	double portW, portH;
	portSize(portW, portH);

	double left, right, bottom, top;
	viewRect(left, right, bottom, top);

	double sizeInView = portW < 1e-5 ? 0.0 : ( fBrushConfig.size() * (right - left) / portW );
	double sizeInViewSquare = sizeInView * sizeInView;

	if( fDragMode == kNormal )
	{
		fCollectedUVs.clear();

		MStatus *returnStatus = NULL;
		MSelectionMask mask = MSelectionMask::kSelectMeshUVs;
		const bool bPickSingle = false;
		MSelectionList	selectionList;

		bool bSelect = MPxTexContext::getMarqueeSelection( x - fBrushConfig.size(), y - fBrushConfig.size(), 
														   x + fBrushConfig.size(), y + fBrushConfig.size(), 
														   mask, bPickSingle, true, selectionList );

		if (bSelect)
		{
			MObject component;
			selectionList.getDagPath( 0, fDagPath, component );
			fDagPath.extendToShape();

			MFnMesh mesh(fDagPath);

			MString currentUVSetName;
			mesh.getCurrentUVSetName(currentUVSetName);

			MIntArray UVsToTest;
			if( component.apiType() == MFn::kMeshMapComponent )
			{
				MFnSingleIndexedComponent compFn( component );
				compFn.getElements( UVsToTest );

				for (unsigned int i = 0; i < UVsToTest.length(); ++i)
				{
					float u, v;
					MStatus bGetUV = mesh.getUV(UVsToTest[i], u, v, &currentUVSetName);
					if (bGetUV == MS::kSuccess)
					{
						float distSquare = ( u - xView ) * ( u - xView ) + ( v - yView ) * ( v - yView );
						if ( distSquare < sizeInViewSquare )
							fCollectedUVs.append(UVsToTest[i]);
					}
				}

			}

			// position in view(world) space. 
			fLastPoint = MPoint( xView, yView, 0.0 );
			fCurrentPoint = MPoint( xView, yView, 0.0 );
		}
	}

	return MS::kSuccess;
}