示例#1
0
MStatus ffdPlanar::getBoundingBox( MDataBlock& block,
                                   unsigned int multiIndex,
                                   MBoundingBox &boundingBoxOut )
{
    MStatus status = MS::kSuccess;
    
    MArrayDataHandle inputHandle = block.outputArrayValue( input );
    inputHandle.jumpToElement( multiIndex );
    MObject mesh = inputHandle.outputValue().child( inputGeom ).asMesh();
    
    MBoundingBox boundingBox = MBoundingBox();
    MFnMesh meshFn( mesh, &status );
    MCheckErr( status, "Error getting mesh from mesh object\n" );
    
    MPointArray pointArray = MPointArray();
    meshFn.getPoints( pointArray, MSpace::kTransform );
    
    for ( int i = 0; i < pointArray.length(); i++ )
    {
        boundingBox.expand( pointArray[i] );
    }
    
    boundingBoxOut = boundingBox;
    return status;
}
// alembic by default sets meshes to be poly unless it's explicitly set to be
// subdivision.  UsdExport makes meshes catmullClark by default.  Here, we
// implement logic to get set the subdivision scheme so that it matches.
static
void
_SetMeshesSubDivisionScheme(
        UsdStagePtr stage,
        const UsdMayaChaserRegistry::FactoryContext::DagToUsdMap& dagToUsd)
{

    for (const auto& p: dagToUsd) {
        const MDagPath& dag = p.first;
        const SdfPath& usdPrimPath = p.second;
        if (!dag.isValid()) {
            continue;
        }

        MStatus status;
        MFnMesh meshFn(dag, &status);
        if (!status) {
            continue;
        }

        if (UsdGeomMesh usdMesh = UsdGeomMesh::Get(stage, usdPrimPath)) {
            MPlug plug = meshFn.findPlug("SubDivisionMesh");
            bool isSubDivisionMesh = (!plug.isNull() && plug.asBool());

            if (!isSubDivisionMesh) {
                usdMesh.GetSubdivisionSchemeAttr().Set(UsdGeomTokens->none);
            }
        }
    }
}
示例#3
0
void tm_polySlot::getMeshUVs()
{
	MDagPath dagPath = getMeshNode();
	MObject meshObject = dagPath.node();
	MFnMesh meshFn( meshObject);

	MStringArray uvSetNames;
	MString currentUVSetName;
	MFloatArray *p_uArray = NULL;
	MFloatArray *p_vArray = NULL;
	MIntArray *p_uvCounts = NULL;
	MIntArray *p_uvIds = NULL;
	unsigned uvSetsCount = meshFn.numUVSets();
	if(uvSetsCount > 0)
	{
		meshFn.getUVSetNames( uvSetNames);
		p_uArray = new MFloatArray[uvSetsCount];
		p_vArray = new MFloatArray[uvSetsCount];
		p_uvCounts = new MIntArray[uvSetsCount];
		p_uvIds = new MIntArray[uvSetsCount];
		meshFn.getCurrentUVSetName( currentUVSetName);
		for( unsigned i = 0; i < uvSetsCount; i++)
		{
			meshFn.getUVs( p_uArray[i], p_vArray[i], &uvSetNames[i]);
			meshFn.getAssignedUVs( p_uvCounts[i], p_uvIds[i], &uvSetNames[i]); 
		}
	}
#ifdef _DEBUG
MString msg;
msg = "Old uvSetsCount = " + uvSetsCount;
msg += "UvSetNames = ";
for(unsigned i=0;i<uvSetNames.length();i++) msg += uvSetNames[i] + ", ";
MGlobal::displayInfo( msg);
#endif
}
示例#4
0
void
OsdPtexMeshData::initializeMesh() 
{
    if (!_hbrmesh)
        return;

    // create far mesh
    OpenSubdiv::FarMeshFactory<OpenSubdiv::OsdVertex>
        meshFactory(_hbrmesh, _level, _adaptive);

    _farmesh = meshFactory.Create(true /*ptex coords*/);

    delete _hbrmesh;
    _hbrmesh = NULL;

    int numTotalVertices = _farmesh->GetNumVertices();

    // create context and vertex buffer
    clearComputeContextAndVertexBuffer();

    if (_kernel == kCPU) {
        _cpuComputeContext = OpenSubdiv::OsdCpuComputeContext::Create(_farmesh);
        _cpuPositionBuffer = OpenSubdiv::OsdCpuGLVertexBuffer::Create(3, numTotalVertices);
        if (not _adaptive)
            _cpuNormalBuffer = OpenSubdiv::OsdCpuGLVertexBuffer::Create(3, numTotalVertices);
#ifdef OPENSUBDIV_HAS_OPENMP
    } else if (_kernel == kOPENMP) {
        _cpuComputeContext = OpenSubdiv::OsdCpuComputeContext::Create(_farmesh);
        _cpuPositionBuffer = OpenSubdiv::OsdCpuGLVertexBuffer::Create(3, numTotalVertices);
        if (not _adaptive)
            _cpuNormalBuffer = OpenSubdiv::OsdCpuGLVertexBuffer::Create(3, numTotalVertices);
#endif
#ifdef OPENSUBDIV_HAS_CUDA
    } else if (_kernel == kCUDA) {
        _cudaComputeContext = OpenSubdiv::OsdCudaComputeContext::Create(_farmesh);
        _cudaPositionBuffer = OpenSubdiv::OsdCudaGLVertexBuffer::Create(3, numTotalVertices);
        if (not _adaptive)
            _cudaNormalBuffer = OpenSubdiv::OsdCudaGLVertexBuffer::Create(3, numTotalVertices);
#endif
#ifdef OPENSUBDIV_HAS_OPENCL
    } else if (_kernel == kCL) {
        _clComputeContext = OpenSubdiv::OsdCLComputeContext::Create(_farmesh, g_clContext);
        _clPositionBuffer = OpenSubdiv::OsdCLGLVertexBuffer::Create(3, numTotalVertices,
                                                                    g_clContext);
        if (not _adaptive)
            _clNormalBuffer = OpenSubdiv::OsdCLGLVertexBuffer::Create(3, numTotalVertices,
                                                                      g_clContext);
#endif
    }

    _needsInitializeMesh = false;

    // get geometry from maya mesh
    MFnMesh meshFn(_meshDagPath);
    meshFn.getPoints(_pointArray);

    _needsUpdate = true;
}
示例#5
0
foundation::auto_release_ptr<renderer::MeshObject> createMesh(const MObject& mobject)
{
    MStatus stat = MStatus::kSuccess;
    MFnMesh meshFn(mobject, &stat);
    CHECK_MSTATUS(stat);

    MPointArray points;
    MFloatVectorArray normals;
    MFloatArray uArray, vArray;
    MIntArray triPointIds, triNormalIds, triUvIds, triMatIds, perFaceAssignments;
    getMeshData(mobject, points, normals, uArray, vArray, triPointIds, triNormalIds, triUvIds, triMatIds, perFaceAssignments);

    foundation::auto_release_ptr<renderer::MeshObject> mesh(
        renderer::MeshObjectFactory::create(
            makeGoodString(meshFn.fullPathName()).asChar(),
            renderer::ParamArray()));

    for (unsigned int i = 0; i < points.length(); i++)
        mesh->push_vertex(mPointToGVector3(points[i]));

    for (unsigned int i = 0; i < normals.length(); i++)
        mesh->push_vertex_normal(mPointToGVector3(normals[i]));

    for (unsigned int i = 0; i < uArray.length(); i++)
    {
        mesh->push_tex_coords(
            renderer::GVector2(
                static_cast<float>(uArray[i]),
                static_cast<float>(vArray[i])));
    }

    const unsigned int numTris = triPointIds.length() / 3;

    for (unsigned int i = 0; i < numTris; i++)
    {
        const int perFaceShadingGroup = triMatIds[i];
        const int vtxId0 = triPointIds[i * 3 + 0];
        const int vtxId1 = triPointIds[i * 3 + 1];
        const int vtxId2 = triPointIds[i * 3 + 2];
        const int normalId0 = triNormalIds[i * 3 + 0];
        const int normalId1 = triNormalIds[i * 3 + 1];
        const int normalId2 = triNormalIds[i * 3 + 2];
        const int uvId0 = triUvIds[i * 3 + 0];
        const int uvId1 = triUvIds[i * 3 + 1];
        const int uvId2 = triUvIds[i * 3 + 2];
        mesh->push_triangle(
            renderer::Triangle(
                vtxId0, vtxId1, vtxId2,
                normalId0, normalId1, normalId2,
                uvId0, uvId1, uvId2,
                perFaceShadingGroup));
    }

    return mesh;
}
//-----------------------------------------------------------------------------
// Adds a color set to the input history of the passed mesh
//-----------------------------------------------------------------------------
MObject ValveMaya::AddColorSetToMesh(
	const MString &colorSetName,
	const MDagPath &mDagPath,
	MDagModifier &mDagModifier )
{
	if ( !mDagPath.hasFn( MFn::kMesh ) )
		return MObject::kNullObj;

	MFnMesh meshFn( mDagPath );
	MString uniqueColorSetName;

	{
		MStringArray colorSetNames;
		meshFn.getColorSetNames( colorSetNames );
		const uint nColorSets( colorSetNames.length() );
		for ( int i( 0 ); uniqueColorSetName.length() == 0; ++i )
		{
			uniqueColorSetName = colorSetName;
			if ( i > 0 )
			{
				uniqueColorSetName += i;
			}
			for ( uint j( 0U ); j != nColorSets; ++j )
			{
				if ( uniqueColorSetName == colorSetNames[ j ] )
				{
					uniqueColorSetName.clear();
					break;
				}
			}
		}
	}

	// Create a 'createColorSet' node
	MObject ccsObj( mDagModifier.MDGModifier::createNode( "createColorSet" ) );
	mDagModifier.doIt();
	const MFnDependencyNode ccsFn( ccsObj );
	MPlug csnP( ccsFn.findPlug( "colorSetName" ) );
	csnP.setValue( uniqueColorSetName );

	// Insert it in the history of the mesh
	MPlug inMeshP( meshFn.findPlug( "inMesh" ) );
	MPlugArray mPlugArray;
	if ( inMeshP.connectedTo( mPlugArray, true, false ) && mPlugArray.length() )
	{
		mDagModifier.disconnect( mPlugArray[ 0 ], inMeshP );
		mDagModifier.connect( mPlugArray[ 0 ], ccsFn.findPlug( "inputGeometry" ) );
	}

	mDagModifier.connect( ccsFn.findPlug( "outputGeometry" ), inMeshP );
	mDagModifier.doIt();

	return ccsObj;
}
示例#7
0
void
OsdMeshData::initializeMesh() 
{
    if (!_hbrmesh)
        return;

    OpenSubdiv::OsdMeshBitset bits;
    bits.set(OpenSubdiv::MeshAdaptive, _adaptive!=0);
    bits.set(OpenSubdiv::MeshFVarData, true);

    if (_kernel == kCPU) {
        _mesh = new OpenSubdiv::OsdMesh<OpenSubdiv::OsdCpuGLVertexBuffer,
                                         OpenSubdiv::OsdCpuComputeController,
                                         OpenSubdiv::OsdGLDrawContext>(
                                                g_cpuComputeController,
                                                _hbrmesh, 3, _level, bits);
#ifdef OPENSUBDIV_HAS_OPENMP
    } else if (_kernel == kOPENMP) {
        _mesh = new OpenSubdiv::OsdMesh<OpenSubdiv::OsdCpuGLVertexBuffer,
                                         OpenSubdiv::OsdOmpComputeController,
                                         OpenSubdiv::OsdGLDrawContext>(
                                                g_ompComputeController,
                                                _hbrmesh, 3, _level, bits);
#endif
#ifdef OPENSUBDIV_HAS_CUDA
    } else if(_kernel == kCUDA) {
        _mesh = new OpenSubdiv::OsdMesh<OpenSubdiv::OsdCudaGLVertexBuffer,
                                         OpenSubdiv::OsdCudaComputeController,
                                         OpenSubdiv::OsdGLDrawContext>(
                                                g_cudaComputeController,
                                                _hbrmesh, 3, _level, bits);
#endif
#ifdef OPENSUBDIV_HAS_OPENCL
    } else if(_kernel == kCL) {
        _mesh = new OpenSubdiv::OsdMesh<OpenSubdiv::OsdCLGLVertexBuffer,
                                         OpenSubdiv::OsdCLComputeController,
                                         OpenSubdiv::OsdGLDrawContext>(
                                                g_clComputeController,
                                                _hbrmesh, 3, _level, bits,
                                                g_clContext, g_clQueue);
#endif
    }

    delete _hbrmesh;
    _hbrmesh = NULL;

    _needsInitializeMesh = false;

    // get geometry from maya mesh
    MFnMesh meshFn(_meshDagPath);
    meshFn.getPoints(_pointArray);

    _needsUpdate = true;
}
void
SubdivUserData::UpdatePoints(MObject mesh)
{
    // update coarse vertex array
    MFnMesh meshFn(mesh);
    MStatus status;

    int nPoints = meshFn.numVertices();
    const float *points = meshFn.getRawPoints(&status);

    // XXX: looking for other good way to detect change
    float total = 0;
    for(int i = 0; i < 3*nPoints; ++i) total += points[i];
    if(_cachedTotal == total) return;
    _cachedTotal = total;

    MFloatVectorArray normals;
    meshFn.getVertexNormals(true, normals);
    if (nPoints != normals.length()) return; // XXX: error


    // Update vertex
    std::vector<float> vertex;
    vertex.resize(nPoints*6);

    for(int i = 0; i < nPoints; ++i){
        vertex[i*6+0] = points[i*3+0];
        vertex[i*6+1] = points[i*3+1];
        vertex[i*6+2] = points[i*3+2];
        vertex[i*6+3] = normals[i].x;
        vertex[i*6+4] = normals[i].y;
        vertex[i*6+5] = normals[i].z;
    }

    _vertexBuffer->UpdateData(&vertex.at(0), nPoints);

/* XXX
    float *varying = new float[_osdmesh.GetNumVaryingElements()];
    _osdmesh.BeginUpdateCoarseVertexVarying();
    for(int i = 0; i < nPoints; ++i){
        varying[0] = normals[i].x;
        varying[1] = normals[i].y;
        varying[2] = normals[i].z;
        _osdmesh.UpdateCoarseVertexVarying(i, varying);
    }
    _osdmesh.EndUpdateCoarseVertexVarying();
    delete[] varying;
*/

    // subdivide
    _osdmesh->Subdivide(_vertexBuffer, NULL);
}
示例#9
0
MStatus meshRemapTool::checkForHistory(const MDagPath& mesh)
{
	MFnMesh	meshFn(mesh);
	MPlug	historyPlug = meshFn.findPlug("inMesh", true);

	if (historyPlug.isDestination())
	{
		MGlobal::displayError("Destination mesh has history. Its geometry cannot be modified.");
		return MS::kInvalidParameter;
	}

	return MS::kSuccess;
}
示例#10
0
// if we have a mesh and it is a bifrost mesh it may contain velocity vertex data
bool MayaObject::hasBifrostVelocityChannel()
{
	MFnMesh meshFn(this->mobject);
	int numColorSets = meshFn.numColorSets();
	MStringArray colorSetNames;
	meshFn.getColorSetNames(colorSetNames);
	for (uint i = 0; i < colorSetNames.length(); i++)
	{
		if (colorSetNames[i] == "bifrostVelocity")
			return true;
	}
	return false;
}
示例#11
0
MStatus updateTCCDataFty::doIt()
//
//	Description:
//		Performs the actual updateTCCData operation on the given object and UVs
//
{
    MStatus status = MS::kSuccess;

    MFnMesh meshFn( fMesh );

    remapMeshData(meshFn);

    return status;
}
示例#12
0
void SoftBodyNode::computeSoftBody(const MPlug &plug, MDataBlock &data)
{
	//	std::cout << "(SoftBodyNode::computeSoftBody) | ";

	MObject thisObject(thisMObject());

	MPlug plgInputMesh(thisObject, inputMesh);

	MObject update;
	//force evaluation of the shape
	plgInputMesh.getValue(update);

	btAssert(plgInputMesh.isConnected());
	MPlugArray connections;
	plgInputMesh.connectedTo(connections, true, false);

	// MFnDependencyNode fnNode(connections[0].node());
	btAssert( connections.length() != 0);

	// std::cout << "(SoftBodyNode::computeSoftBody) Dependency node fn name: | " << fnNode.name() << std::endl;

	MFnMesh meshFn(connections[0].node());

	MFnDagNode fnDagNode(thisObject);    
	MFnTransform fnTransform(fnDagNode.parent(0));
	MVector mtranslation = fnTransform.getTranslation(MSpace::kTransform);
	MQuaternion mrotation;
	fnTransform.getRotation(mrotation, MSpace::kObject);

	std::cout << "(SoftBodyNode::computeSoftBody) fnTranform: | " << fnTransform.name().asChar() << std::endl;
	std::cout << "(SoftBodyNode::computeSoftBody) fnTranform: | " << mtranslation.x << ", " << mtranslation.y << ", " 
		<< mtranslation.z << std::endl;
	solver_t::remove_soft_body(this->m_soft_body);
	std::vector<int> triVertIndices;
	std::vector<float> triVertCoords;

	createHelperMesh(meshFn, triVertIndices, triVertCoords, MSpace::kTransform);
	this->m_soft_body = solver_t::create_soft_body(triVertCoords, triVertIndices);

	solver_t::add_soft_body(this->m_soft_body, this->name().asChar());
	//	this->m_soft_body->set_transform(vec3f((float)mtranslation.x, (float)mtranslation.y, (float)mtranslation.z),
	//								quatf((float)mrotation.w, (float)mrotation.x, (float)mrotation.y, (float)mrotation.z));

	data.outputValue(ca_softBody).set(true);
	data.setClean(plug);

}
示例#13
0
void MayaGeoAttribute::transferValueFromMaya(MPlug &plug, MDataBlock &data){
	MDataHandle dataHandle = data.inputValue(plug);
	MFnMesh meshFn(dataHandle.asMesh());
	
	MFloatPointArray mayaPoints;
	meshFn.getPoints(mayaPoints);
	
	// collect points
	std::vector<Imath::V3f> coralPoints;
	for(int i = 0; i < mayaPoints.length(); ++i){
		MFloatPoint* mayaPoint = &mayaPoints[i];
		coralPoints.push_back(Imath::V3f(mayaPoint->x, mayaPoint->y, mayaPoint->z));
	}
	
	// collect faces
	int numPolys =  meshFn.numPolygons();
	std::vector<std::vector<int> > coralFaces(numPolys);
	for(int polyId = 0; polyId < numPolys; ++polyId){
		MIntArray mayaVertexList;
		meshFn.getPolygonVertices(polyId, mayaVertexList);
		
		int polyPoints = mayaVertexList.length();
		std::vector<int> coralFace(polyPoints);
		for(int i = 0; i < polyPoints; ++i){
			int pointId = mayaVertexList[i];
			coralFace[i] = pointId;
		}
		
		coralFaces[polyId] = coralFace;
	}
	
	// create coral geo
	coral::Geo *coralGeo = outValue();
	
	if(coralGeo->hasSameTopology(coralFaces)){
		coralGeo->setPoints(coralPoints);
	}
	else{
		coralGeo->build(coralPoints, coralFaces);
	}
	
	valueChanged();
}
示例#14
0
void MayaObject::getMeshData(MPointArray& points, MFloatVectorArray& normals)
{
	MStatus stat;
	MObject meshObject = this->mobject;
	MMeshSmoothOptions options;
	MFnMesh tmpMesh(this->mobject);
	MFnMeshData meshData;
	MObject dataObject;
	MObject smoothedObj;

	// create smooth mesh if needed
	if (tmpMesh.findPlug("displaySmoothMesh").asBool())
	{
		stat = tmpMesh.getSmoothMeshDisplayOptions(options);
		if (stat)
		{
			if (!tmpMesh.findPlug("useSmoothPreviewForRender", false, &stat).asBool())
			{
				//Logging::debug(MString("useSmoothPreviewForRender turned off"));
				int smoothLevel = tmpMesh.findPlug("renderSmoothLevel", false, &stat).asInt();
				options.setDivisions(smoothLevel);
			}
			if (options.divisions() > 0)
			{
				dataObject = meshData.create();
				smoothedObj = tmpMesh.generateSmoothMesh(dataObject, &options, &stat);
				if (stat)
				{
					meshObject = smoothedObj;
				}
			}
		}
	}
	MFnMesh meshFn(meshObject, &stat);
	if (!stat)
	{
		MString error = stat.errorString();
		Logging::error(error);
	}
	meshFn.getPoints(points);
	meshFn.getNormals(normals, MSpace::kObject);
}
示例#15
0
//---------------------------------------------------------------------
void	componentConverter::getContainedEdges(	MIntArray& vtxIDs,
												MIntArray& result	)
//---------------------------------------------------------------------
{
//	result.clear();

	MFnMesh meshFn(mesh);
	MItMeshVertex vertIter(mesh);

	BPT_BA searchArray(meshFn.numEdges());
	
	MIntArray conEdges;
	

	
	unsigned int l = vtxIDs.length();
	int indexValue;
	for(unsigned i = 0;i < l;i++)
	{
		vertIter.setIndex(vtxIDs[i],tmp);
		vertIter.getConnectedEdges(conEdges);
		
		
		
		for(unsigned int x = 0; x < conEdges.length(); x++)
		{
			indexValue = conEdges[x];
			if( searchArray[indexValue] )
			{
				result.append(indexValue);
			}
			else
				searchArray.setBitTrue(indexValue);
		}
	}




}
示例#16
0
void tm_polySlot::setMeshUVs()
{
	MStatus status( MStatus::kSuccess);
	MDagPath dagPath = getMeshNode();
	MObject meshObject = dagPath.node();
	MFnMesh meshFn( meshObject);
#ifdef _DEBUG
MString msg;
uvSetsCount = meshFn.numUVSets();
if(uvSetsCount > 0) meshFn.getUVSetNames( uvSetNames);
msg = "Old uvSetsCount = " + uvSetsCount;
msg += "UvSetNames = ";
for(unsigned i=0;i<uvSetNames.length();i++) msg += uvSetNames[i] + ", ";
MGlobal::displayInfo( msg);
#endif
	
/*	for( unsigned i = 0; i < uvSetNames.length(); i++)
	{
		status = meshFn.deleteUVSet( uvSetNames[i], &dgModifier);
		if(!status) MGlobal::displayError("Can't delete uvSet " + uvSetNames[i]);
	}
*/
//	i = 0;
	for( unsigned i = 0; i < uvSetsCount; i++)
	{
//		status = meshFn.setCurrentUVSetName( uvSetNames[i]);
//			if(!status) MGlobal::displayError("Can't set current " + uvSetNames[i] + " uvSet.");
//		status = meshFn.deleteUVSet( uvSetNames[i]);
//		if(!status) MGlobal::displayError("Can't delete uvSet " + uvSetNames[i]);
//		meshFn.clearUVs( &uvSetNames[i]);
//		status = meshFn.createUVSet( uvSetNames[i]);
//		if(!status) MGlobal::displayError("Can't create uvSet " + uvSetNames[i]);
		status = meshFn.setUVs( p_uArray[i], p_vArray[i], &uvSetNames[i]);
		if(!status) MGlobal::displayError("Can't set uvSet " + uvSetNames[i]);
		status = meshFn.assignUVs( p_uvCounts[i], p_uvIds[i], &uvSetNames[i]);
		if(!status) MGlobal::displayError("Can't assign uvSet " + uvSetNames[i]);
	}
}
示例#17
0
void LuxRenderer::defineTriangleMesh(mtlu_MayaObject *obj, bool noObjectDef = false)
{
	MObject meshObject = obj->mobject;
	MStatus stat = MStatus::kSuccess;
	MFnMesh meshFn(meshObject, &stat);
	
	CHECK_MSTATUS(stat);
	MItMeshPolygon faceIt(meshObject, &stat);
	CHECK_MSTATUS(stat);

	MPointArray points;
	meshFn.getPoints(points);
    MFloatVectorArray normals;
    meshFn.getNormals( normals, MSpace::kWorld );
	MFloatArray uArray, vArray;
	meshFn.getUVs(uArray, vArray);

	logger.debug(MString("Translating mesh object ") + meshFn.name().asChar());
	MString meshFullName = obj->fullNiceName;


	MIntArray trianglesPerFace, triVertices;
	meshFn.getTriangles(trianglesPerFace, triVertices);
	int numTriangles = 0;
	for( size_t i = 0; i < trianglesPerFace.length(); i++)
		numTriangles += trianglesPerFace[i];

	// lux render does not have a per vertex per face normal definition, here we can use one normal and uv per vertex only
	// So I create the triangles with unique vertices, normals and uvs. Of course this way vertices etc. cannot be shared.
	int numPTFloats = numTriangles * 3 * 3;
	logger.debug(MString("Num Triangles: ") + numTriangles + " num tri floats " + numPTFloats);

	float *floatPointArray = new float[numPTFloats];
	float *floatNormalArray = new float[numPTFloats];
	float *floatUvArray = new float[numTriangles * 3 * 2];
	
	logger.debug(MString("Allocated ") + numPTFloats + " floats for point and normals");

	MIntArray triangelVtxIdListA;
	MFloatArray floatPointArrayA;

	MPointArray triPoints;
	MIntArray triVtxIds;
	MIntArray faceVtxIds;
	MIntArray faceNormalIds;
	
	int *triangelVtxIdList = new int[numTriangles * 3];

	for( uint sgId = 0; sgId < obj->shadingGroups.length(); sgId++)
	{
		MString slotName = MString("slot_") + sgId;
	}
	
	int triCount = 0;
	int vtxCount = 0;

	for(faceIt.reset(); !faceIt.isDone(); faceIt.next())
	{
		int faceId = faceIt.index();
		int numTris;
		faceIt.numTriangles(numTris);
		faceIt.getVertices(faceVtxIds);

		MIntArray faceUVIndices;

		faceNormalIds.clear();
		for( uint vtxId = 0; vtxId < faceVtxIds.length(); vtxId++)
		{
			faceNormalIds.append(faceIt.normalIndex(vtxId));
			int uvIndex;
			faceIt.getUVIndex(vtxId, uvIndex);
			faceUVIndices.append(uvIndex);
		}

		int perFaceShadingGroup = 0;
		if( obj->perFaceAssignments.length() > 0)
			perFaceShadingGroup = obj->perFaceAssignments[faceId];
		//logger.info(MString("Face ") + faceId + " will receive SG " +  perFaceShadingGroup);

		for( int triId = 0; triId < numTris; triId++)
		{
			int faceRelIds[3];
			faceIt.getTriangle(triId, triPoints, triVtxIds);

			for( uint triVtxId = 0; triVtxId < 3; triVtxId++)
			{
				for(uint faceVtxId = 0; faceVtxId < faceVtxIds.length(); faceVtxId++)
				{
					if( faceVtxIds[faceVtxId] == triVtxIds[triVtxId])
					{
						faceRelIds[triVtxId] = faceVtxId;
					}
				}
			}

			
			uint vtxId0 = faceVtxIds[faceRelIds[0]];
			uint vtxId1 = faceVtxIds[faceRelIds[1]];
			uint vtxId2 = faceVtxIds[faceRelIds[2]];
			uint normalId0 = faceNormalIds[faceRelIds[0]];
			uint normalId1 = faceNormalIds[faceRelIds[1]];
			uint normalId2 = faceNormalIds[faceRelIds[2]];
			uint uvId0 = faceUVIndices[faceRelIds[0]];
			uint uvId1 = faceUVIndices[faceRelIds[1]];
			uint uvId2 = faceUVIndices[faceRelIds[2]];
			
			floatPointArray[vtxCount * 3] = points[vtxId0].x;
			floatPointArray[vtxCount * 3 + 1] = points[vtxId0].y;
			floatPointArray[vtxCount * 3 + 2] = points[vtxId0].z;

			floatNormalArray[vtxCount * 3] = normals[normalId0].x;
			floatNormalArray[vtxCount * 3 + 1] = normals[normalId0].y;
			floatNormalArray[vtxCount * 3 + 2] = normals[normalId0].z;

			floatUvArray[vtxCount * 2] = uArray[uvId0];
			floatUvArray[vtxCount * 2 + 1] = vArray[uvId0];

			vtxCount++;

			floatPointArray[vtxCount * 3] = points[vtxId1].x;
			floatPointArray[vtxCount * 3 + 1] = points[vtxId1].y;
			floatPointArray[vtxCount * 3 + 2] = points[vtxId1].z;

			floatNormalArray[vtxCount * 3] = normals[normalId1].x;
			floatNormalArray[vtxCount * 3 + 1] = normals[normalId1].y;
			floatNormalArray[vtxCount * 3 + 2] = normals[normalId1].z;

			floatUvArray[vtxCount * 2] = uArray[uvId1];
			floatUvArray[vtxCount * 2 + 1] = vArray[uvId1];

			vtxCount++;

			floatPointArray[vtxCount * 3] = points[vtxId2].x;
			floatPointArray[vtxCount * 3 + 1] = points[vtxId2].y;
			floatPointArray[vtxCount * 3 + 2] = points[vtxId2].z;

			floatNormalArray[vtxCount * 3] = normals[normalId2].x;
			floatNormalArray[vtxCount * 3 + 1] = normals[normalId2].y;
			floatNormalArray[vtxCount * 3 + 2] = normals[normalId2].z;

			floatUvArray[vtxCount * 2] = uArray[uvId2];
			floatUvArray[vtxCount * 2 + 1] = vArray[uvId2];

			vtxCount++;
			
			//logger.debug(MString("Vertex count: ") + vtxCount + " maxId " + ((vtxCount - 1) * 3 + 2) + " ptArrayLen " + (numTriangles * 3 * 3));

			triangelVtxIdList[triCount * 3] = triCount * 3;
			triangelVtxIdList[triCount * 3 + 1] = triCount * 3 + 1;
			triangelVtxIdList[triCount * 3 + 2] = triCount * 3 + 2;

			triCount++;
		}		
	}

//generatetangents 	bool 	Generate tangent space using miktspace, useful if mesh has a normal map that was also baked using miktspace (such as blender or xnormal) 	false
//subdivscheme 	string 	Subdivision algorithm, options are "loop" and "microdisplacement" 	"loop"
//displacementmap 	string 	Name of the texture used for the displacement. Subdivscheme parameter must always be provided, as load-time displacement is handled by the loop-subdivision code. 	none - optional. (loop subdiv can be used without displacement, microdisplacement will not affect the mesh without a displacement map specified)
//dmscale 	float 	Scale of the displacement (for an LDR map, this is the maximum height of the displacement in meter) 	0.1
//dmoffset 	float 	Offset of the displacement. 	0
//dmnormalsmooth 	bool 	Smoothing of the normals of the subdivided faces. Only valid for loop subdivision. 	true
//dmnormalsplit 	bool 	Force the mesh to split along breaks in the normal. If a mesh has no normals (flat-shaded) it will rip open on all edges. Only valid for loop subdivision. 	false
//dmsharpboundary 	bool 	Try to preserve mesh boundaries during subdivision. Only valid for loop subdivision. 	false
//nsubdivlevels 	integer 	Number of subdivision levels. This is only recursive for loop subdivision, microdisplacement will need much larger values (such as 50). 	0

	bool generatetangents = false;
	getBool(MString("mtlu_mesh_generatetangents"), meshFn, generatetangents);
	int subdivscheme = 0;
	const char *subdAlgos[] = {"loop", "microdisplacement"};
	getInt(MString("mtlu_mesh_subAlgo"), meshFn, subdivscheme);
	const char *subdalgo =  subdAlgos[subdivscheme];
	float dmscale;
	getFloat(MString("mtlu_mesh_dmscale"), meshFn, dmscale);
	float dmoffset;
	getFloat(MString("mtlu_mesh_dmoffset"), meshFn, dmoffset);
	MString displacementmap;
	getString(MString("mtlu_mesh_displacementMap"), meshFn, displacementmap);
	const char *displacemap = displacementmap.asChar();
	bool dmnormalsmooth = true;
	getBool(MString("mtlu_mesh_dmnormalsmooth"), meshFn, dmnormalsmooth);
	bool dmnormalsplit = false;
	getBool(MString("mtlu_mesh_dmnormalsplit"), meshFn, dmnormalsplit);
	bool dmsharpboundary = false;
	getBool(MString("mtlu_mesh_dmsharpboundary"), meshFn, dmsharpboundary);
	int nsubdivlevels = 0;
	getInt(MString("mtlu_mesh_subdivlevel"), meshFn, nsubdivlevels);

	// a displacment map needs its own texture defintion
	MString displacementTextureName = "";
	if(displacementmap.length() > 0)
	{
		ParamSet dmParams = CreateParamSet();
		dmParams->AddString("filename", &displacemap);
		displacementTextureName = meshFn.name() + "_displacementMap";
		this->lux->texture(displacementTextureName.asChar(), "float", "imagemap", boost::get_pointer(dmParams));
	}

	ParamSet triParams = CreateParamSet();
	int numPointValues = numTriangles * 3;
	int numUvValues = numTriangles * 3 * 2;
	clock_t startTime = clock();
	logger.info(MString("Adding mesh values to params."));
	triParams->AddInt("indices", triangelVtxIdList, numTriangles * 3);
	triParams->AddPoint("P", floatPointArray, numPointValues);
	triParams->AddNormal("N", floatNormalArray, numPointValues);
	triParams->AddFloat("uv",  floatUvArray, numUvValues);
	if( nsubdivlevels > 0)
		triParams->AddInt("nsubdivlevels", &nsubdivlevels, 1);
	triParams->AddBool("generatetangents",  &generatetangents, 1);
	triParams->AddString("subdivscheme", &subdalgo , 1);
	if(displacementmap.length() > 0)
	{
		triParams->AddFloat("dmoffset",  &dmoffset, 1);
		triParams->AddFloat("dmscale",  &dmscale, 1);
		const char *dmft = displacementTextureName.asChar();
		triParams->AddString("displacementmap", &dmft);
	}
	triParams->AddBool("dmnormalsmooth",  &dmnormalsmooth, 1);
	triParams->AddBool("dmnormalsplit",  &dmnormalsplit, 1);
	triParams->AddBool("dmsharpboundary",  &dmsharpboundary, 1);


	clock_t pTime = clock();
	if(!noObjectDef)
		this->lux->objectBegin(meshFullName.asChar());
	this->lux->shape("trianglemesh", boost::get_pointer(triParams));
	if(!noObjectDef)
		this->lux->objectEnd();

	clock_t eTime = clock();
	logger.info(MString("Timing: Parameters: ") + ((pTime - startTime)/CLOCKS_PER_SEC) + " objTime " + ((eTime - pTime)/CLOCKS_PER_SEC) + " all " + ((eTime - startTime)/CLOCKS_PER_SEC));

	return;

}
示例#18
0
MStatus meshOpFty::doIt()
//
//	Description:
//		Performs the operation on the selected mesh and components
//
{
	MStatus status;
	unsigned int i, j;

	// Get access to the mesh's function set
	//
	MFnMesh meshFn(fMesh);

	// The division count argument is used in many of the operations
	// to execute the operation multiple subsequent times. For example,
	// with a division count of 2 in subdivide face, the given faces will be
	// divide once and then the resulting inner faces will be divided again.
	//
	int divisionCount = 2;

	MFloatVector translation;
	if (fOperationType == kExtrudeEdges
		|| fOperationType == kExtrudeFaces
		|| fOperationType == kDuplicateFaces
		|| fOperationType == kExtractFaces)
	{
		// The translation vector is used for the extrude, extract and 
		// duplicate operations to move the result to a new position. For 
		// example, if you extrude an edge on a mesh without a subsequent 
		// translation, the extruded edge will be on at the position of the 
		// orignal edge and the created faces will have no area.
		// 
		// Here, we provide a translation that is in the same direction as the
		// average normal of the given components.
		//
		MFn::Type componentType = getExpectedComponentType(fOperationType);
		MIntArray adjacentVertexList;
		switch (componentType)
		{
		case MFn::kMeshEdgeComponent:
			for (i = 0; i < fComponentIDs.length(); ++i)
			{
				int2 vertices;
				meshFn.getEdgeVertices(fComponentIDs[i], vertices);
				adjacentVertexList.append(vertices[0]);
				adjacentVertexList.append(vertices[1]);
			}
			break;

		case MFn::kMeshPolygonComponent:
			for (i = 0; i < fComponentIDs.length(); ++i)
			{
				MIntArray vertices;
				meshFn.getPolygonVertices(fComponentIDs[i], vertices);
				for (j = 0; j < vertices.length(); ++j)
					adjacentVertexList.append(vertices[j]);
			}
			break;
		default:	
			break;
		}
		MVector averageNormal(0, 0, 0);
		for (i = 0; i < adjacentVertexList.length(); ++i)
		{
			MVector vertexNormal;
			meshFn.getVertexNormal(adjacentVertexList[i], vertexNormal,
				MSpace::kWorld);
			averageNormal += vertexNormal;
		}
		if (averageNormal.length() < 0.001)
			averageNormal = MVector(0.0, 1.0, 0.0);
		else averageNormal.normalize();
		translation = averageNormal;
	}

	// When doing an extrude operation, there is a choice of extrude the
	// faces/edges individually or together. If extrudeTogether is true and 
	// multiple adjacent components are selected, they will be extruded as if
	// it were one more complex component.
	//
	// The following variable sets that option.
	//
	bool extrudeTogether = true;

	// Execute the requested operation
	//
	switch (fOperationType)
	{
	case kSubdivideEdges: {
		status = meshFn.subdivideEdges(fComponentIDs, divisionCount);
		CHECK_STATUS(status);
		break; }

	case kSubdivideFaces: {
		status = meshFn.subdivideFaces(fComponentIDs, divisionCount);
		CHECK_STATUS(status);
		break; }

	case kExtrudeEdges: {
		status = meshFn.extrudeEdges(fComponentIDs, divisionCount,
			&translation, extrudeTogether);
		CHECK_STATUS(status);
		break; }

	case kExtrudeFaces: {
		status = meshFn.extrudeFaces(fComponentIDs, divisionCount,
			&translation, extrudeTogether);
		CHECK_STATUS(status);
		break; }

	case kCollapseEdges: {
		status = meshFn.collapseEdges(fComponentIDs);
		CHECK_STATUS(status);
		break; }

	case kCollapseFaces: {
		status = meshFn.collapseFaces(fComponentIDs);
		CHECK_STATUS(status);
		break; }

	case kDuplicateFaces: {
		status = meshFn.duplicateFaces(fComponentIDs, &translation);
		CHECK_STATUS(status);
		break; }

	case kExtractFaces: {
		status = meshFn.extractFaces(fComponentIDs, &translation);
		CHECK_STATUS(status);
		break; }

	case kSplitLightning: {
		status = doLightningSplit(meshFn);
		CHECK_STATUS(status);
		break; }

	default:
		status = MS::kFailure;
		break;
	}

	return status;
}
示例#19
0
void VMesh::save(const char* filename, int isStart)
{
	MStatus status;
	MFnMesh meshFn(pgrow, &status );
	MItMeshPolygon faceIter( pgrow, &status );
	MItMeshVertex vertIter(pgrow, &status);
	
	int m_n_triangle=0, m_n_vertex=0;
	MIntArray m_vertex_id;
	MFloatArray facevarying_s, facevarying_t;
	MPointArray m_vertex_p;
	MVectorArray m_vertex_n, m_vertex_t;
	
	meshFn.getPoints(m_vertex_p, MSpace::kWorld);
	float auv[2];
	faceIter.reset();
	for( ; !faceIter.isDone(); faceIter.next() ) 
	{
		MIntArray vexlist;
		faceIter.getVertices ( vexlist );
		m_n_triangle += vexlist.length() - 2;
		for( unsigned int i=1; i < vexlist.length()-1; i++ ) 
		{
			m_vertex_id.append(vexlist[0]);
			m_vertex_id.append(vexlist[i]);
			m_vertex_id.append(vexlist[i+1]);
			faceIter.getUV(0, auv);
			facevarying_s.append(auv[0]);
			facevarying_t.append(auv[1]);
			faceIter.getUV(i, auv);
			facevarying_s.append(auv[0]);
			facevarying_t.append(auv[1]);
			faceIter.getUV(i+1, auv);
			facevarying_s.append(auv[0]);
			facevarying_t.append(auv[1]);
		}
	}
	
	XYZ* pbinormal = new XYZ[meshFn.numVertices()];
	XYZ* pv = new XYZ[meshFn.numVertices()];
	float* pscale = new float[meshFn.numVertices()];
	float* curlarray = new float[meshFn.numVertices()];
	float* widtharray = new float[meshFn.numVertices()];
	float* densityarray = new float[meshFn.numVertices()];
	
	MVector tnor, tang, ttang, binormal, dir, hair_up, hair_v;
	MPoint tpos;
	MColor Cscale, Cerect, Crotate, Cstiff, Ccurl, Cwidth, Cdensity;
	float rot;
	MATRIX44F hair_space, hair_space_inv;
	
	MString setScale("fb_scale");
	MString setErect("fb_erect");
	MString setRotate("fb_rotate");
	MString setStiff("fb_stiffness");
	MString setCurl("fb_curl");
	MString setWidth("fb_width");
	MString setDensity("fb_density");
	MIntArray conn_face;
	
	XYZ dP;
	
	vertIter.reset();
	for( int i=0; !vertIter.isDone(); vertIter.next(), i++ )
	{
		vertIter.getConnectedFaces(conn_face);
		
		vertIter.getNormal(tnor, MSpace::kWorld);
		tnor.normalize();
		m_vertex_n.append(tnor);
		
		vertIter.getColor(Cscale, &setScale);
		vertIter.getColor(Cerect, &setErect);
		vertIter.getColor(Crotate, &setRotate);
		vertIter.getColor(Cstiff, &setStiff);
		vertIter.getColor(Ccurl, &setCurl);
		vertIter.getColor(Cwidth, &setWidth);
		vertIter.getColor(Cdensity, &setDensity);
		if(Cstiff.r < 0.1) Cstiff.r = 0.1;
		
		tang = MVector(0,0,0);
		
		for(int j=0; j<conn_face.length(); j++)
		{
			meshFn.getFaceVertexTangent (conn_face[j], i, ttang,  MSpace::kWorld);
			ttang.normalize();
			tang += ttang;
		}
		tang /= conn_face.length();
		conn_face.clear();
		tang.normalize();
		
		tang = tnor^tang;
		tang.normalize();
		
		binormal = tnor^tang;
		
		if(Crotate.r<0.5)
		{
			rot = (0.5 - Crotate.r)*2;
			tang = tang + (binormal-tang)*rot;
			tang.normalize();
			binormal = tnor^tang;
		}
		else
		{
			rot = (Crotate.r-0.5)*2;
			tang = tang + (binormal*-1-tang)*rot;
			tang.normalize();
			binormal = tnor^tang;
		}
		
		pbinormal[i] = XYZ(binormal.x, binormal.y, binormal.z);
		pscale[i] = Cscale.r * m_scale;
		
		dir = tang + (tnor - tang)*Cerect.r;
		dir.normalize();
		
		m_vertex_t.append(dir);
		
		hair_up = dir^binormal;
		//pup[i] = XYZ(hair_up.x, hair_up.y, hair_up.z);
		
		hair_space.setIdentity();
		hair_space.setOrientations(XYZ(binormal.x, binormal.y, binormal.z), XYZ(hair_up.x, hair_up.y, hair_up.z), XYZ(dir.x, dir.y, dir.z));
		hair_space.setTranslation(XYZ(m_vertex_p[i].x, m_vertex_p[i].y, m_vertex_p[i].z));
		hair_space_inv = hair_space;
		hair_space_inv.inverse();
		
		hair_v = getVelocity(i);
		dP = XYZ(hair_v.x, hair_v.y, hair_v.z);
		hair_space_inv.transformAsNormal(dP);
		if(dP.y<0) dP.y = 0;
		dP *= m_wind/Cstiff.r;
		
		pv[i] = dP;
		
		curlarray[i] = Ccurl.r;
		widtharray[i] = Cwidth.r;
		densityarray[i] = Cdensity.r;
	}

	m_n_vertex = meshFn.numVertices();
	
	FXMLTriangleMap fmap;
	fmap.beginMap(filename);
	
// write vertex id
	string static_path(filename);
	zGlobal::cutByFirstDot(static_path);
	static_path.append(".hbs");
	
	if(isStart == 1)
	{
		fmap.staticBegin(static_path.c_str(), m_n_triangle);
	
		int* id_list = new int[m_n_triangle*3];
		for(int i=0; i<m_n_triangle*3; i++) id_list[i] = m_vertex_id[i];
	
		fmap.addVertexId(m_n_triangle*3, id_list);
		delete[] id_list;
		
		float* sarray = new float[m_n_triangle*3];
		float* tarray = new float[m_n_triangle*3];
		for(int i=0; i<m_n_triangle*3; i++) 
		{
			sarray[i] = facevarying_s[i];
			tarray[i] = facevarying_t[i];
		}
		fmap.addStaticFloatArray("root_s", m_n_triangle*3, sarray);
		fmap.addStaticFloatArray("root_t", m_n_triangle*3, tarray);
		
		delete[] sarray;
		delete[] tarray;
		
		XYZ* recpref = new XYZ[m_n_vertex];
	
		for(int i=0; i<m_n_vertex; i++) recpref[i] = XYZ(m_vertex_p[i].x, m_vertex_p[i].y, m_vertex_p[i].z);
		fmap.addPref(m_n_vertex, recpref);
		delete[] recpref;
		
		fmap.addStaticFloatArray("scale", m_n_vertex, pscale);
		
		fmap.addStaticFloatArray("curl", m_n_vertex, curlarray);

		fmap.addStaticFloatArray("width", m_n_vertex, widtharray);
	
		fmap.addStaticFloatArray("density", m_n_vertex, densityarray);
	
		fmap.staticEnd();
	}
	else
	{
		fmap.staticBeginNoWrite(static_path.c_str(), m_n_triangle);
	
		fmap.addVertexId(m_n_triangle*3);
		fmap.addStaticFloatArray("root_s", m_n_triangle*3);
		fmap.addStaticFloatArray("root_t", m_n_triangle*3);
		fmap.addPref(m_n_vertex);
		fmap.addStaticFloatArray("scale", m_n_vertex);
		fmap.addStaticFloatArray("curl", m_n_vertex);
		fmap.addStaticFloatArray("width", m_n_vertex);
		fmap.addStaticFloatArray("density", m_n_vertex);
		
		fmap.staticEndNoWrite();
	}
	
	delete[] curlarray;
	delete[] widtharray;
	delete[] densityarray;

// write vertex p
	string dynamic_path(filename);
	zGlobal::cutByLastDot(dynamic_path);
	dynamic_path.append(".hbd");
	
	fmap.dynamicBegin(dynamic_path.c_str());
	
	XYZ* recp = new XYZ[m_n_vertex];
	
	for(int i=0; i<m_n_vertex; i++) recp[i] = XYZ(m_vertex_p[i].x, m_vertex_p[i].y, m_vertex_p[i].z);
	fmap.addP(m_n_vertex, recp);
	delete[] recp;
	
// write vertex n
	XYZ* recn = new XYZ[m_n_vertex];
	
	for(int i=0; i<m_n_vertex; i++) recn[i] = XYZ(m_vertex_n[i].x, m_vertex_n[i].y, m_vertex_n[i].z);
	fmap.addN(m_n_vertex, recn);
	delete[] recn;
	
// write veretx tangent
	XYZ* rect = new XYZ[m_n_vertex];
	
	for(int i=0; i<m_n_vertex; i++) rect[i] = XYZ(m_vertex_t[i].x, m_vertex_t[i].y, m_vertex_t[i].z);
	fmap.addDynamicVectorArray("direction", m_n_vertex, rect);
	delete[] rect;
	
// write vertex binormal
	fmap.addDynamicVectorArray("binormal", m_n_vertex, pbinormal);
	delete[] pbinormal;
	

	
// write vertex up
//	fmap.addDynamicVectorArray("up", m_n_vertex, pup);
//	delete[] pup;
	
// write vertex wind
	fmap.addDynamicVectorArray("wind", m_n_vertex, pv);
	delete[] pv;

// write bound box	
	MPoint corner_l, corner_h;
	
	getBBox(corner_l, corner_h);
	
	fmap.addBBox(corner_l.x, corner_l.y, corner_l.z, corner_h.x, corner_h.y, corner_h.z);
	
	fmap.dynamicEnd();
	
	fmap.endMap(filename);
	
	char info[256];
	sprintf(info, "hairBase writes %s", filename);
	MGlobal::displayInfo ( info );
	
	m_vertex_id.clear();
	m_vertex_p.clear();
	m_vertex_n.clear();
	m_vertex_t.clear();

	delete[] pscale;
}
示例#20
0
MStatus tm_polySplitFty::doIt()
//
//	Description:
//		Performs the actual tm_polySplit operation on the given object and UVs
//
{
	MStatus status = MS::kSuccess;

	MVector vector;
	MPoint point;
	MFnMesh meshFn( fMesh);
	int edgeVertices[2];
	MItMeshEdge edgeIt( fMesh);
	int prevIndex;

	meshFn.getEdgeVertices( fSelEdges[0], edgeVertices);
	meshFn.getPoint( edgeVertices[0], point);
	meshFn.getPoint( edgeVertices[1], averagePos);
	averagePos = (point + averagePos) * 0.5;

#ifdef _DEBUG
cout << endl << "##########################tm_polySplitFty::doIt" << endl;
cout<<"loop="<<fa_loop<<" loopMode="<<fa_loop_mode<<" loop_angle="<<fa_loop_angle<<" loop_maxcount="<<fa_maxcount<<endl;
#endif
	//getting valid edges
	{
		if( fa_loop)
		{
			if(!getLoopFromFirst( fa_loop_mode, fa_loop_angle, fa_maxcount))
			{
				MGlobal::displayError( "tm_polySplit command failed: Bad edges selected." );
				return MStatus::kFailure;
			}
		}
		else
		{
			if(!getRing())
			{
				MGlobal::displayError( "tm_polySplit command failed: Bad edges selected." );
				return MStatus::kFailure;
			}
		}
		{// close edges:
		MIntArray conFacesA;
		edgeIt.setIndex( fSelEdges[0], prevIndex);
		edgeIt.getConnectedFaces( conFacesA);
		if( conFacesA.length() > 1)
		{
			MIntArray conFacesB;
			edgeIt.setIndex( fSelEdges[fSelEdges.length() - 1], prevIndex);
			edgeIt.getConnectedFaces( conFacesB);
			if( conFacesB.length() > 1)
			{
				if( conFacesA[0] == conFacesB[0]) fSelEdges.append( fSelEdges[0]);
				else if( conFacesA[0] == conFacesB[1]) fSelEdges.append( fSelEdges[0]);
				else if( conFacesA[1] == conFacesB[0]) fSelEdges.append( fSelEdges[0]);
				else if( conFacesA[1] == conFacesB[1]) fSelEdges.append( fSelEdges[0]);
			}
		}
		}
	}

#ifdef _DEBUG
cout << endl << "fSelEdges = ";for( unsigned i=0;i<fSelEdges.length();i++) cout << fSelEdges[i] << " ";cout << endl;
#endif

	edgesCount = fSelEdges.length();
	if(edgesCount < 2)
	{
		MGlobal::displayError( "tm_polySplit command failed: Can't find more than one ring edge." );
		return MStatus::kFailure;
	}

	MItMeshVertex vtxIt( fMesh);
	MItMeshPolygon faceIt( fMesh);

	MIntArray conFaces;
	MIntArray conEdges;
	MIntArray faceEdges;

	unsigned numConFaces;

	if( firstTime)
	{
	splitedPoints_start_N.setLength( edgesCount);
	splitedPoints_dir_N.setLength( edgesCount);
	splitedPoints_ndir_N.setLength( edgesCount);
	splitedPoints_start_R.setLength( edgesCount);
	splitedPoints_dir_R.setLength( edgesCount);
	splitedPoints_ndir_R.setLength( edgesCount);

	oldVtxCount = meshFn.numVertices();
	oldUVsCount = meshFn.numUVs();

#ifdef _DEBUG
cout << endl << "oldVtxCount = " << oldVtxCount << endl;
cout << endl << "oldUVsCount = " << oldUVsCount << endl;
#endif

//######################################## finding inverted edges
	invEdge.setLength(edgesCount);
#ifdef _DEBUG
cout << "### finding inverted edges:" << endl;
#endif
	for( unsigned i = 0; i < edgesCount; i++) invEdge[i] = 0;
	int zero_vtx_index = 0;
	edgeIt.setIndex( fSelEdges[0], prevIndex);
	edgeIt.getConnectedFaces( conFaces);
	numConFaces = conFaces.length();
	int nextEdgeId = -1;
	int nextFaceId = -1;
	for( unsigned cf = 0; cf < numConFaces; cf++)
	{
		faceIt.setIndex( conFaces[cf], prevIndex);
		faceIt.getEdges( faceEdges);
		unsigned numFaceEdges = faceEdges.length();
		for( unsigned fe = 0; fe < numFaceEdges; fe++)
		{
			if( faceEdges[fe] == fSelEdges[1])
			{
				nextFaceId = conFaces[cf];
				break;
			}
		}
		if( nextEdgeId != -1) break;
	}
	if( nextFaceId == -1)
	{
#ifdef _DEBUG
cout << "nextFaceId == -1 (edgeId[" << fSelEdges[0] << "]);" << endl;
#endif
		return MStatus::kFailure;
	}
	meshFn.getEdgeVertices( fSelEdges[0], edgeVertices);
	int vtxIndex = edgeVertices[zero_vtx_index];
	unsigned e = 1;
	bool founded = true;
	int nextEdgeVertices[2];
	int COUNTER = 0;
	while( e < edgesCount)
	{
		COUNTER++;
		if(COUNTER > 32000)
		{
#ifdef _DEBUG
cout << "(COUNTER > 32000) on finding inverted edges!" << endl;
#endif
			break;
		}
		meshFn.getEdgeVertices( fSelEdges[e], nextEdgeVertices);
		vtxIt.setIndex( vtxIndex, prevIndex);
		vtxIt.getConnectedEdges( conEdges);
		unsigned numConEdges = conEdges.length();
		faceIt.setIndex( nextFaceId, prevIndex);
		faceIt.getEdges( faceEdges);
		unsigned numFaceEdges = faceEdges.length();
#ifdef _DEBUG
cout << COUNTER << ") edgeId = " << fSelEdges[e-1] << ", numConEdges = " << numConEdges;
cout << ", vtxIndex = " << vtxIndex << ", nextFaceId = " << nextFaceId << ":" << endl;
#endif
		bool nextEdgeId_founded = false;
		for( unsigned ce = 0; ce < numConEdges; ce++)
		{
			if((conEdges[ce] == fSelEdges[e-1]) || (conEdges[ce] == nextEdgeId)) continue;
			for( unsigned fe = 0; fe < numFaceEdges; fe++)
			{
				if( conEdges[ce] == faceEdges[fe])
				{
					nextEdgeId = conEdges[ce];
					nextEdgeId_founded = true;
					break;
				}
			}
			if( nextEdgeId_founded) break;
		}
if(!nextEdgeId_founded)
{
#ifdef _DEBUG
cout << "nextEdgeId was not founded, edge " <<  fSelEdges[e-1] << endl;
cout << "connected edges: ";
for( unsigned ce = 0; ce < numConEdges; ce++) cout << conEdges[ce] << ", "; cout << endl;
cout << "connected face edges: ";
for( unsigned fe = 0; fe < numFaceEdges; fe++) cout << faceEdges[fe] << ", "; cout << endl;
#endif
break;
}
		int cEdgeVertices[2];
		meshFn.getEdgeVertices( nextEdgeId, cEdgeVertices);
		int cEdge_oppVtx;
		int searchVtxIndex = 1;
		if( nextEdgeId == fSelEdges[e]) searchVtxIndex = 0;
		if( cEdgeVertices[0] == vtxIndex) cEdge_oppVtx = cEdgeVertices[1];
		else cEdge_oppVtx = cEdgeVertices[0];
#ifdef _DEBUG
cout << "nextEdgeId = " << nextEdgeId << ", cEdge_oppVtx = " << cEdge_oppVtx << endl;
#endif
		founded = false;
		if(cEdge_oppVtx == nextEdgeVertices[searchVtxIndex])
		{
			invEdge[e] = 1;
			zero_vtx_index = 1;
			founded = true;
		}
		if(cEdge_oppVtx == nextEdgeVertices[1-searchVtxIndex])
		{
			zero_vtx_index = 0;
			founded = true;
		}
		if(!founded)
		{
			vtxIndex = cEdge_oppVtx;
			continue;
		}
		if(e == (edgesCount-1)) break;
		edgeIt.setIndex( fSelEdges[e], prevIndex);
		edgeIt.getConnectedFaces( conFaces);
		numConFaces = conFaces.length();
		if( numConFaces < 2)
		{
#ifdef _DEBUG
cout << "numConFaces < 2 (edgeId[" << fSelEdges[e] << "]);" << endl;
#endif
			break;
		}
		if( conFaces[0] == nextFaceId) nextFaceId = conFaces[1];
		else nextFaceId = conFaces[0];
		vtxIndex = nextEdgeVertices[zero_vtx_index];
		e++;
#ifdef _DEBUG
cout << "founded, conFaces = " << conFaces[0] << ", " << conFaces[1] << " => " << nextFaceId << endl;
#endif
	}
	}
//######################################## getting edges vertices UVs information
	MFloatArray edgeUVs_u( edgesCount*4, -1.0f);
	MFloatArray edgeUVs_v( edgesCount*4, -1.0f);
	MIntArray edge_conFacesIds( edgesCount*2, -1);
	MIntArray edge_conFacesNum( edgesCount, -1);
	for( unsigned e = 0; e < edgesCount; e++)
	{
//#ifdef _DEBUG
//cout << "edgeId #" << fSelEdges[e] << ":" << endl;
//#endif
		meshFn.getEdgeVertices( fSelEdges[e], edgeVertices);
		edgeIt.setIndex( fSelEdges[e], prevIndex);
		edgeIt.getConnectedFaces( conFaces);
		numConFaces = conFaces.length();
		edge_conFacesNum[e] = numConFaces;
		bool swap = false;
		if((numConFaces > 1) && (conFaces[0] > conFaces[1])) swap = true;
		for( unsigned cf = 0; cf < numConFaces; cf++)
		{
			int cFaceId = cf;
			if( swap) cFaceId = 1 - cf;
			edge_conFacesIds[e*2 + cf] = conFaces[cFaceId];
			for( int ev = 0; ev < 2 ; ev++)
			{
				int numVtxUVs;
				float uvPiont[2];
				vtxIt.setIndex( edgeVertices[ev], prevIndex);
				vtxIt.numUVs( numVtxUVs);
				if( numVtxUVs <= 0) continue;
				MStatus stat = vtxIt.getUV( conFaces[cFaceId], uvPiont);
				if(!stat) continue;
				unsigned uvArrayIndex = (e*4) + (cf*2) + ev;
				edgeUVs_u.set( uvPiont[0], uvArrayIndex);
				edgeUVs_v.set( uvPiont[1], uvArrayIndex);
//#ifdef _DEBUG
//cout << "faceId #" << conFaces[cFaceId] << ", vtxId #" << edgeVertices[ev] << " = (";
//cout << edgeUVs_u[uvArrayIndex] << ", " << edgeUVs_v[uvArrayIndex] << ");" << endl;
//#endif
			}
		}
	}
//###################################### get points starts and vectors:
	for( unsigned i = 0; i < edgesCount; i++)
	{
		meshFn.getEdgeVertices( fSelEdges[i], edgeVertices);
		if ( invEdge[i] == 1)
		{
			meshFn.getPoint( edgeVertices[1], splitedPoints_start_N[i]);
			meshFn.getPoint( edgeVertices[0], point);
		}
		else
		{
			meshFn.getPoint( edgeVertices[0], splitedPoints_start_N[i]);
			meshFn.getPoint( edgeVertices[1], point);
		}
		splitedPoints_dir_N[i] = point - splitedPoints_start_N[i];
		splitedPoints_ndir_N[i] = splitedPoints_dir_N[i];
		splitedPoints_ndir_N[i].normalize();
		splitedPoints_start_R[i] = point;
		splitedPoints_dir_R[i] = splitedPoints_start_N[i] - point;
		splitedPoints_ndir_R[i] = splitedPoints_dir_R[i];
		splitedPoints_ndir_R[i].normalize();
	}
/*
#ifdef _DEBUG
cout << endl << "splitedPoints_start_N = ";
for( unsigned i=0;i<splitedPoints_start_N.length();i++)
	cout << splitedPoints_start_N[0]<<","<<splitedPoints_start_N[1]<<","<<splitedPoints_start_N[2] << " ";
cout << endl << "splitedPoints_dir_N = ";
for( unsigned i=0;i<splitedPoints_dir_N.length();i++)
	cout << splitedPoints_dir_N[0]<<","<<splitedPoints_dir_N[1]<<","<<splitedPoints_dir_N[2] << " ";
cout << endl;
#endif
*/
//######################################## do the split:
	MFloatPointArray internalPoints;
	MIntArray placements( edgesCount, MFnMesh::kOnEdge);
	MFloatArray edgeFactors( edgesCount, 0.5);
status = meshFn.split( placements, fSelEdges, edgeFactors, internalPoints);
	if( !status)
	{
		MGlobal::displayError( "can't split with given data");
		return status;
	}
#ifdef _DEBUG
cout << endl << " ! split success ! " << endl;
#endif
	newVtxCount = meshFn.numVertices();
	newUVsCount = meshFn.numUVs();
//###################################### get UVs starts and vectors:
#ifdef _DEBUG
cout << endl << "newVtxCount = " << newVtxCount << endl;
cout << endl << "newUVsCount = " << newUVsCount << endl;
#endif

	unsigned edgeNum = 0;
	unsigned uvNum = 0;
	unsigned numNewUVs = newUVsCount - oldUVsCount;
	splitedUVsU_start_N.setLength( numNewUVs);
	splitedUVsV_start_N.setLength( numNewUVs);
	splitedUVsU_start_R.setLength( numNewUVs);
	splitedUVsV_start_R.setLength( numNewUVs);
	splitedUVsU_dir_N.setLength( numNewUVs);
	splitedUVsV_dir_N.setLength( numNewUVs);
	splitedUVsU_dir_R.setLength( numNewUVs);
	splitedUVsV_dir_R.setLength( numNewUVs);
	splitedUVsU_ndir_N.setLength( numNewUVs);
	splitedUVsV_ndir_N.setLength( numNewUVs);
	splitedUVsU_ndir_R.setLength( numNewUVs);
	splitedUVsV_ndir_R.setLength( numNewUVs);
	for( int j = oldVtxCount; j < newVtxCount; j++)
	{
		MIntArray conFaces;
		int numVtxUVs;
		vtxIt.setIndex( j, prevIndex);
		vtxIt.numUVs( numVtxUVs);
		if( numVtxUVs > 0)
		{
//#ifdef _DEBUG
//cout << "vtx #" << j << " (edge #" << fSelEdges[edgeNum] << ") :" << endl;
//#endif
			bool swap = false;
			if((edge_conFacesNum[edgeNum] > 1) && (numVtxUVs > 1))
			{
				MItMeshPolygon faceIt( fMesh);
				faceIt.setIndex( edge_conFacesIds[edgeNum*2], prevIndex);
				int numFaceVtx = faceIt.polygonVertexCount();
				bool has = false;
//#ifdef _DEBUG
//cout << "((numConFaces > 1) && (numVtxUVs > 1)) : ( ";
//#endif
				for( int fVtx = 0; fVtx < numFaceVtx; fVtx++)
				{
					int uvIndex;
					faceIt.getUVIndex( fVtx, uvIndex);
//#ifdef _DEBUG
//cout << uvIndex << " ";
//#endif
					if( uvIndex == (uvNum + oldUVsCount)) has = true;
				}
				if( !has) swap = true;
//#ifdef _DEBUG
//cout << ") uv = " << (uvNum + oldUVsCount) << " => swap = " << swap << endl;
//#endif
			}
			for( int uvi = 0; uvi < numVtxUVs; uvi++)
			{
				unsigned uvArrayIndex_a;
				if( swap) uvArrayIndex_a = (edgeNum*4) + ((1-uvi)*2);
				else uvArrayIndex_a = (edgeNum*4) + (uvi*2);
				unsigned uvArrayIndex_b = uvArrayIndex_a;
				if(invEdge[edgeNum] == 1) uvArrayIndex_a++;
				else uvArrayIndex_b++;
				splitedUVsU_start_N[uvNum] = edgeUVs_u[uvArrayIndex_a];
				splitedUVsV_start_N[uvNum] = edgeUVs_v[uvArrayIndex_a];
				splitedUVsU_start_R[uvNum] = edgeUVs_u[uvArrayIndex_b];
				splitedUVsV_start_R[uvNum] = edgeUVs_v[uvArrayIndex_b];
				splitedUVsU_dir_N[uvNum] = edgeUVs_u[uvArrayIndex_b] - edgeUVs_u[uvArrayIndex_a];
				splitedUVsV_dir_N[uvNum] = edgeUVs_v[uvArrayIndex_b] - edgeUVs_v[uvArrayIndex_a];
				splitedUVsU_dir_R[uvNum] = edgeUVs_u[uvArrayIndex_a] - edgeUVs_u[uvArrayIndex_b];
				splitedUVsV_dir_R[uvNum] = edgeUVs_v[uvArrayIndex_a] - edgeUVs_v[uvArrayIndex_b];
				float dist = sqrt((splitedUVsU_dir_N[uvNum]*splitedUVsU_dir_N[uvNum]) + (splitedUVsV_dir_N[uvNum]*splitedUVsV_dir_N[uvNum]));
				if(dist == 0)
				{
					splitedUVsU_ndir_N[uvNum] = 0;
					splitedUVsV_ndir_N[uvNum] = 0;
					splitedUVsU_ndir_R[uvNum] = 0;
					splitedUVsV_ndir_R[uvNum] = 0;
				}
				else
				{
					splitedUVsU_ndir_N[uvNum] = splitedUVsU_dir_N[uvNum] / dist;
					splitedUVsV_ndir_N[uvNum] = splitedUVsV_dir_N[uvNum] / dist;
					splitedUVsU_ndir_R[uvNum] = splitedUVsU_dir_R[uvNum] / dist;
					splitedUVsV_ndir_R[uvNum] = splitedUVsV_dir_R[uvNum] / dist;
				}
/*#ifdef _DEBUG
cout << "uvNum #" << (uvNum + oldUVsCount) << " (uvi=" << uvi << ") : ( ";
cout << edgeUVs_u[uvArrayIndex_a] << ", ";
cout << edgeUVs_v[uvArrayIndex_a] << ") - ( ";
cout << edgeUVs_u[uvArrayIndex_b] << ", ";
cout << edgeUVs_v[uvArrayIndex_b] << ");" << endl;
#endif
*/						uvNum++;
			}
		}
		edgeNum++;
	}
//##################################################################################
	return status;
}
示例#21
0
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;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
MStatus CVstSelectCoincidentFacesCmd::DoSelect()
{
	MSelectionList meshList;
	GetSpecifiedMeshes( meshList );

	MSelectionList coincidentList;

	MDagPath mDagPath;
	MObject cObj;

	MPointArray points;
	MIntArray iIndexes;
	MIntArray jIndexes;

	uint iCount;
	bool addI;
	bool same;
	bool foundVertex;

	double tolerance( MPoint_kTol );
	if ( m_undo.ArgDatabase().isFlagSet( kOptTolerance ) )
	{
		MDistance optTolerance;
		m_undo.ArgDatabase().getFlagArgument( kOptTolerance, 0U, optTolerance );
		tolerance = optTolerance.as( MDistance::internalUnit() );
	}

	for ( MItSelectionList sIt( meshList ); !sIt.isDone(); sIt.next() )
	{
		if ( !sIt.getDagPath( mDagPath, cObj ) )
			continue;

		MFnSingleIndexedComponent sFn;
		MObject sObj( sFn.create( MFn::kMeshPolygonComponent ) );

		MFnMesh meshFn( mDagPath );
		meshFn.getPoints( points );

		if ( !sIt.hasComponents() )
		{
			const uint nFaces( meshFn.numPolygons() );
			for ( uint i( 0U ); i != nFaces; ++i )
			{
				meshFn.getPolygonVertices( i, iIndexes );
				iCount = iIndexes.length();

				addI = false;

				for ( uint j( i + 1 ); j < nFaces; ++j )
				{
					meshFn.getPolygonVertices( j, jIndexes );
					if ( jIndexes.length() == iCount )
					{
						same = true;

						for ( uint k( 0U ); k != iCount; ++k )
						{
							foundVertex = false;

							const MPoint &kPoint( points[ iIndexes[ k ] ] );

							for ( uint l( 0U ); l < iCount; ++l )
							{
								if ( kPoint.isEquivalent( points[ jIndexes[ l ] ], tolerance ) )
								{
									foundVertex = true;
									break;
								}
							}

							if ( !foundVertex )
							{
								same = false;
								break;
							}
						}

						if ( same )
						{
							addI = true;
							sFn.addElement( j );
						}
					}
				}

				if ( addI )
				{
					sFn.addElement( i );
				}
			}
		}
		else
		{
			MFnSingleIndexedComponent cFn( cObj );
			MIntArray cA;
			MFnSingleIndexedComponent( cObj ).getElements( cA );

			const uint nFaces( cA.length() );

			for ( uint i( 0U ); i != nFaces; ++i )
			{
				meshFn.getPolygonVertices( cA[ i ], iIndexes );
				iCount = iIndexes.length();

				addI = false;

				for ( uint j( i + 1U ); j < nFaces; ++j )
				{
					meshFn.getPolygonVertices( cA[ j ], jIndexes );
					if ( jIndexes.length() == iCount )
					{
						same = true;

						for ( uint k( 0U ); k != iCount; ++k )
						{
							foundVertex = false;

							const MPoint &kPoint( points[ iIndexes[ k ] ] );

							for ( uint l( 0U ); l < iCount; ++l )
							{
								if ( kPoint.isEquivalent( points[ jIndexes[ l ] ], tolerance ) )
								{
									foundVertex = true;
									break;
								}
							}

							if ( !foundVertex )
							{
								same = false;
								break;
							}
						}

						if ( same )
						{
							addI = true;
							sFn.addElement( cA[ j ] );
						}
					}
				}

				if ( addI )
				{
					sFn.addElement( cA[ i ] );
				}
			}
		}

		if ( sFn.elementCount() > 0 )
		{
			coincidentList.add( mDagPath, sObj );
		}
		else
		{
			MSelectionList tmpList;
			tmpList.add( mDagPath, cObj );
			MStringArray tmpA;
			tmpList.getSelectionStrings( tmpA );

			minfo << "No coincident faces on:";
			for ( uint i( 0U ); i != tmpA.length(); ++i )
			{
				minfo << " " << tmpA[ i ];
			}
			minfo << std::endl;
		}
	}

	if ( coincidentList.length() )
	{
		MGlobal::setActiveSelectionList( coincidentList );
		MStringArray tmpA;
		coincidentList.getSelectionStrings( tmpA );
		setResult( tmpA );
	}
	else
	{
		if ( meshList.length() > 0U )
		{
			minfo << "No coincident faces found" << std::endl;
		}
	}

	return MS::kSuccess;
}
示例#23
0
void VMesh::draw()
{
	if(!has_mesh) return;
	
	MStatus status;
	MFnMesh meshFn(pgrow, &status );
	MItMeshVertex vertIter(pgrow, &status);
	
	MPoint S;
	MVector N, tang, ttang, binormal, dir, hair_up;
	MColor Cscale, Cerect, Crotate, Ccurl;
	float rot;
	MATRIX44F hair_space;
	
	MString setScale("fb_scale");
	MString setErect("fb_erect");
	MString setRotate("fb_rotate");
	MString setCurl("fb_curl");
	MIntArray conn_face;
	glBegin(GL_LINES);
	for( int i=0; !vertIter.isDone(); vertIter.next(), i++ )
	{
		//S = vertIter.position(MSpace::kWorld);
		//glVertex3f(S.x, S.y, S.z);
		
		vertIter.getNormal(N, MSpace::kWorld);
		N.normalize();
		
		vertIter.getColor(Cscale, &setScale);
		vertIter.getColor(Cerect, &setErect);
		vertIter.getColor(Crotate, &setRotate);
		vertIter.getColor(Ccurl, &setCurl);
		
		vertIter.getConnectedFaces(conn_face);
		tang = MVector(0,0,0);
		for(int j=0; j<conn_face.length(); j++)
		{
			meshFn.getFaceVertexTangent (conn_face[j], i, ttang,  MSpace::kWorld);
			ttang.normalize();
			tang += ttang;
		}
		tang /= conn_face.length();
		conn_face.clear();
		tang.normalize();
		tang = N^tang;
		tang.normalize();
		
		binormal = N^tang;
		
		if(Crotate.r<0.5)
		{
			rot = (0.5 - Crotate.r)*2;
			tang = tang + (binormal-tang)*rot;
			tang.normalize();
			binormal = N^tang;
		}
		else
		{
			rot = (Crotate.r-0.5)*2;
			tang = tang + (binormal*-1-tang)*rot;
			tang.normalize();
			binormal = N^tang;
		}
		
		dir = tang + (N - tang)*Cerect.r;
		dir.normalize();
		
		//S = S+dir*Cscale.r*m_scale;
		//glVertex3f(S.x, S.y, S.z);
		
		hair_up = dir^binormal;
		
		hair_space.setIdentity();
		hair_space.setOrientations(XYZ(binormal.x, binormal.y, binormal.z), XYZ(hair_up.x, hair_up.y, hair_up.z), XYZ(dir.x, dir.y, dir.z));
		
		S = vertIter.position(MSpace::kWorld);
		
		hair_space.setTranslation(XYZ(S.x, S.y, S.z));
		
		fb->create(Cscale.r*m_scale, 0, Cscale.r*m_scale*(Ccurl.r-0.5)*2);
		
		XYZ pw;
	
		for(int j=0; j<NUMBENDSEG; j++)
		{
			fb->getPoint(j, pw);
			hair_space.transform(pw);
			glVertex3f(pw.x, pw.y, pw.z);
			
			fb->getPoint(j+1, pw);
			hair_space.transform(pw);
			glVertex3f(pw.x, pw.y, pw.z);
		}

		
	}
	glEnd();
	
}
示例#24
0
//----------------------------------------------------------------------------
MStatus		BPT_InsertVtx::doCompleteCompute( MDataBlock& data )
//----------------------------------------------------------------------------
{

				SPEED("Berechne EdgeSplit neu: ");

				MStatus status;

				MPRINT("MACHE KOMPLETTE BERECHNUNG")



				MDataHandle inMeshHandle = data.inputValue(IVinMesh);
				MDataHandle outMeshHandle = data.outputValue(IVoutMesh);


					//splitCount setzen
				
				MDataHandle countHandle	= data.inputValue(IVcount);			
				fIVfty.setCount(countHandle.asInt());
			
				

				MDataHandle spinHandle = data.inputValue(IVspin);

				fIVfty.setSpin(spinHandle.asInt());
				

				int initialVtxCount;	//wird spueueter benueuetigt, um das ValidIndicesArray gleich in der rictigen grueueueuee zu erstellen und zu schreiben


				//gleich zu beginn muss der MeshPath initialisiert werden, damit der MeshPath an die fty ueuebergeben werden kann
				// Dies geschieht besser durch die STE - sie ist darauf ausgelegt
				softTransformationEngine::gatherAttributeObjects(thisMObject());
				softTransformationEngine::saveMeshPathes();

				

				fIVfty.setMeshPath(meshPath);
				
				
			
				MDataHandle	rHandle = data.inputValue(IVslideRelative);
				fIVfty.setRelative(rHandle.asInt());
				
				
				MDataHandle nRelativeHandle = data.inputValue(IVnormalRelative);
				fIVfty.setNormalRelative(nRelativeHandle.asInt());
				
				
				//selection setzen
				MFnIntArrayData		intDataArray;	
				
				MDataHandle arrayHandle = data.inputValue(IVselEdgeIDs);
				intDataArray.setObject(arrayHandle.data());
				
				fIVfty.setEdgeIDs( intDataArray.array() );

				arrayHandle = data.inputValue(IVselVertIDs);
				intDataArray.setObject(arrayHandle.data());

				fIVfty.setVertIDs(intDataArray.array());
				

				//				optionen holen
				
				arrayHandle = data.inputValue(IVoptions);
				intDataArray.setObject(arrayHandle.data());
				MIntArray optionsArray(intDataArray.array());
				

				fIVfty.setOptions(optionsArray);
				
				
				
				
				MDataHandle slideHandle = data.inputValue(IVslide);
				fIVfty.setSlide(slideHandle.asDouble());

				
				//whichSide attribute wird nur fueuer SLide selbst verwendet und kann nicht bereits beim command gestetzt werden
				
				


				MObject inMeshRef = inMeshHandle.asMesh();
				fIVfty.setMesh(inMeshRef);


				MFnMesh meshFn(inMeshHandle.asMesh());
				initialVtxCount = meshFn.numVertices();
				

				

				//ACTION
				try
				{
					status = fIVfty.doIt();
				}
				
				catch(...)
				{
					MGlobal::displayError(" An unknown, severe, error occoured.\nIf it happens again in this situation, please write a bug report.\nPlease undo the operation and save your work!");
					return MS::kUnknownParameter;
				}

				
				MObject newOutMesh = fIVfty.getMesh();

				
				outMeshHandle.set(newOutMesh);

				
				// ---------------------
				// SOFT TRANSFORMATION
				// ---------------------
				// VtxSet setzen - hier reicht es, wenn er einfach die neuen Vtx nimmt


				softTransformationEngine::setVtxSet(data);

		

				//------------SELECTION ROUTINE----------------------


			
				//nur wenn sich spin nicht verueuendert hat, darf ne neue selection gemacht werden - dies wird auch von der IV berueuecksichtigt
				//die selection wird nur noch einmal ausgefueuehrt, weshalb scriptJobInitiated nicht mehr gesetzt wird vom scriptjob
				if( optionsArray[6] && !scriptJobInitated && !(meshPath.apiType() == MFn::kInvalid) )
				{
						
						//auf jeden Fall erstmal die neuen Vertizen holen, damit die anderen prozeduren auch darauf arbeiten kueuennen

						//alles neuen Vertces sollen gewueuehlt werden, also einfach alle Indices eintragen vom initialVtxCount
						//bis zum jetzigen VtxCount
						MIntArray validEdges, validFaces;
						componentConverter CC(newOutMesh);

						int i = 0;


						meshFn.setObject(newOutMesh);
						int newCount = meshFn.numVertices();
						
						validIndices.clear();
						validIndices.setLength(newCount - initialVtxCount);
						
						

						for(; initialVtxCount < newCount; initialVtxCount++)
							validIndices[i++] = initialVtxCount;
						
						

					
					if(optionsArray[6] == 1 || optionsArray[6] == 2) //select edges
					{
						
						CC.getContainedEdges(validIndices,validEdges);
					}


					BPT_Helpers helper;


					if(optionsArray[6] == 2) //select Faces
					{
						CC.getConnectedFaces(validEdges,validFaces);

						//jetzt kann gleich alles beendet werden, da hiernach keine componente mehr kommt, in die man faces umwandeln mueuesste
						validIndices.clear();
						validIndices.append(2);

						
						helper.addIntArrayToLHS(validIndices,validFaces);

					}

					if(optionsArray[6] == 1)
					{//edges fertigmachen
						
						validIndices.clear();
						validIndices.append(1);

						helper.addIntArrayToLHS(validIndices,validEdges);

					}
					else if(optionsArray[6] == 5)
						validIndices.insert(3,0);


					//component Mode umschalten bei bedarf
					if(optionsArray[5])
					{
						MSelectionMask::SelectionType type = MSelectionMask::kSelectMeshVerts;
						
						if(optionsArray[6] == 5)
						{
							type = MSelectionMask::kSelectMeshVerts;
						}
						else if(optionsArray[6] == 2)
						{
							type = MSelectionMask::kSelectMeshFaces;
						}
						else if(optionsArray[6] == 1)
						{
							type = MSelectionMask::kSelectMeshEdges;
						}
						
						
						MSelectionMask mask(type);
						
						
						MGlobal:: setComponentSelectionMask(mask);
					}


					eID = MEventMessage::addEventCallback("idle",IV_makeSelection,this);

					scriptJobInitated = true;

				}
				else
				{//ansonsten muss die SelectionList neu aufgebaut werden, allerdings ohne komponenten
					//diese Aktion solte auch nur einmal ausgefueuehrt werden

					//gegenwueuertige selection holen
					MSelectionList currentList;
					MSelectionList newList;
					MGlobal::getActiveSelectionList(currentList);

					//durch die Liste iterieren und Komponenten Filtern
					MItSelectionList selIter(currentList);
					MObject currentObj;
					for( ; !selIter.isDone();selIter.next() )
					{
						
						selIter.getDependNode(currentObj);
						
						newList.add(currentObj);
					}

					MGlobal::setActiveSelectionList(newList, MGlobal::kAddToList);


		


				}


				



				return status;

}
示例#25
0
void
OsdPtexMeshData::rebuildHbrMeshIfNeeded(OpenSubdivPtexShader *shader)
{
    MStatus status;

    if (!_meshTopoDirty && !shader->getHbrMeshDirty())
        return;

    MFnMesh meshFn(_meshDagPath, &status);
    if (status != MS::kSuccess) return;

    int level = shader->getLevel();
    if (level < 1) level =1;

    SchemeType scheme = shader->getScheme();
    if (scheme == kLoop) scheme = kCatmark;  // XXX: avoid loop for now

    // Get Maya vertex topology and crease data
    MIntArray vertexCount;
    MIntArray vertexList;
    meshFn.getVertices(vertexCount, vertexList);

    MUintArray edgeIds;
    MDoubleArray edgeCreaseData;
    meshFn.getCreaseEdges(edgeIds, edgeCreaseData);

    MUintArray vtxIds;
    MDoubleArray vtxCreaseData;
    meshFn.getCreaseVertices(vtxIds, vtxCreaseData);

    if (vertexCount.length() == 0) return;

    // Cache attribute values
    _level              = shader->getLevel();
    _scheme             = shader->getScheme();
    _kernel             = shader->getKernel();
    _adaptive           = shader->isAdaptive();
    _interpBoundary     = shader->getInterpolateBoundary();

    // Copy Maya vectors into std::vectors
    std::vector<int> numIndices(&vertexCount[0], &vertexCount[vertexCount.length()]);
    std::vector<int> faceIndices(&vertexList[0], &vertexList[vertexList.length()]);
    std::vector<int> vtxCreaseIndices(&vtxIds[0], &vtxIds[vtxIds.length()]);
    std::vector<double> vtxCreases(&vtxCreaseData[0], &vtxCreaseData[vtxCreaseData.length()]);
    std::vector<double> edgeCreases(&edgeCreaseData[0], &edgeCreaseData[edgeCreaseData.length()]);

    // Edge crease index is stored as pairs of vertex ids
    int nEdgeIds = edgeIds.length();
    std::vector<int> edgeCreaseIndices;
    edgeCreaseIndices.resize(nEdgeIds*2);
    for (int i = 0; i < nEdgeIds; ++i) {
        int2 vertices;
        status = meshFn.getEdgeVertices(edgeIds[i], vertices);
        if (status.error()) {
            status.perror("ERROR can't get creased edge vertices");
            continue;
        }
        edgeCreaseIndices[i*2] = vertices[0];
        edgeCreaseIndices[i*2+1] = vertices[1];
    }

    // Convert attribute enums to HBR enums (this is why the enums need to match)
    // XXX use some sort of built-in transmorgification avoid assumption?
    HbrMeshUtil::SchemeType hbrScheme = (HbrMeshUtil::SchemeType) _scheme;
    OsdHbrMesh::InterpolateBoundaryMethod hbrInterpBoundary = 
            (OsdHbrMesh::InterpolateBoundaryMethod) _interpBoundary;

    // Convert Maya mesh to internal HBR representation
    _hbrmesh = ConvertToHBR(meshFn.numVertices(), numIndices, faceIndices,
                            vtxCreaseIndices, vtxCreases,
                            std::vector<int>(), std::vector<float>(),
                            edgeCreaseIndices, edgeCreases,
                            hbrInterpBoundary, 
                            hbrScheme,
                            true );                     // add ptex indices to HBR

    // note: GL function can't be used in prepareForDraw API.
    _needsInitializeMesh = true;

    // Mesh topology data is up to date
    _meshTopoDirty = false;
    shader->setHbrMeshDirty(false);
}
示例#26
0
//-----------------------------------------------------------------
MStatus		ByronsPolyTools::doIt(const MArgList& args)
//-----------------------------------------------------------------
{
    // Ist die version abgelaufen ?
    //
#ifdef EXPIRES

    if( ! checkExpires() )
    {
        MGlobal::displayError( "This AlphaVersion is expired. Scenes will still load properly. " );

        return MS::kSuccess;
    }

#endif

    MSelectionList sList;


    MStatus	status;
    MArgDatabase	argData(syntax(),args);



    if(argData.isFlagSet("-help"))
    {
        MGlobal::executeCommand("showBPTHelpWindow",false,false);
        return MS::kSuccess;
    }



//SELECTION UEBERPRUEFEN

//	Selection holen
//
    argData.getObjects(sList);

//	OrigList fuer UndoZwecke speichern
    origList = sList;






//	Check, ob ueberhaupt Objekt gewaehlt

    if ( (sList.length() == 0) )

    {

        displayError("ONE mesh or its transform node must be selected.");

        return MStatus::kFailure;

    }



    //MDagPath			meshDagPath;

    MItSelectionList sIter(sList);//,MFn::kMesh);
    bool meshOK = false,hasComps = false;

    INVIS(cout<<"SELECTIONLIST LAENGE: "<<sList.length()<<endl);

    for(; !sIter.isDone(); sIter.next())
    {
        sIter.getDagPath(meshDagPath, components);
        //sList.getDagPath(0, meshDagPath, components);








        //if(!meshDagPath.hasFn(MFn::kPluginDependNode))
        if(meshDagPath.apiType() == (MFn::kMesh))
        {

            if(!meshDagPath.hasFn(MFn::kMesh) )
                meshOK = false;
            else
                meshOK = true;





            if( components.apiType() == MFn::kInvalid )
                hasComps = false;
            else
            {
                hasComps = true;
                break;
            }

        }


    }


    if(!meshOK)
    {
        displayError("Invalid type!  Only a mesh or its transform with selected components can be specified!");
        return MStatus::kFailure;
    }



#ifdef	DEMO

    MFnMesh	meshFn(meshDagPath);
    if(meshFn.numPolygons() > 500)
    {
        MGlobal::displayError("This DEMO will only work on meshes with a maximum number of 500 polygons");
        return MS::kFailure;
    }

#endif



    if(!hasComps)
    {
        displayError("Please select some components to operate on");
        return MStatus::kFailure;
    }



//	Flags und Argumente Holen
//----------------------------------

    if(argData.isFlagSet("-iv"))
        operationMode = 0;
    else
        operationMode = 1;


    //zuerst mal edgeComoponents holen - wenn welche vorhanden und -peb flag gesetzt, dann wird auf jeden Fall der case 0 mode verwendet
    getEdgeComponents(sList);

    if( argData.isFlagSet("-peb") && edgeIDs.length() != 0 )
        operationMode = 0;


//------------------------------------
//	OPTIONS
//------------------------------------


    switch(operationMode)
    {
    case 0://insert Vtx mode
    {
        if(argData.isFlagSet("-ic"))
            argData.getFlagArgument("-ic",0,initialCount);
        else
            initialCount = 1;

        goto default_values;

    }

    case 1:	//PolyToolsMode
    {


        //------------------------------------
        //	FLAGS
        //------------------------------------








        smartSplitFlagSet = argData.isFlagSet("-smartSplit");
        edgeLoopFlagSet = argData.isFlagSet("-edgeLoop");
        edgeRingFlagSet = argData.isFlagSet("-edgeRing");
        boundaryFlagSet = argData.isFlagSet("-boundary");

        chamferFlagSet = argData.isFlagSet("-chamfer");
        solidChamferFlagSet = argData.isFlagSet("-solidChamfer");

        smcFlagSet = argData.isFlagSet("-smartMoveComponent");

        growFlagSet = argData.isFlagSet("-gro");
        schrinkFlagSet = argData.isFlagSet("-shr");



        //	abbruch, wenn flags nicht eindeutig und actionMode nicht gesetzt werden kann
        status = setActionMode();

        if(status == MS::kFailure)
            return status;


        //-------------------ENDE-----------------------------


        goto default_values;


    }
    default:
    {
default_values:




        avt = (argData.isFlagSet("-avf"))?true:false;
        avm = (argData.isFlagSet("-avm"))?true:false;


        options.setLength(10);

        options[0] = argData.isFlagSet("-connectEnds");

        options[1] = argData.isFlagSet("-triangulateEnds");

        if(argData.isFlagSet("-maxEdgeCount"))
            argData.getFlagArgument("-maxEdgeCount",0,options[2]);
        else
            options[2] = 16666666;

        options[3] = 0;	//side ist standardmaessig 0:


        if(argData.isFlagSet("-snl") )
            options[4] = 1;
        else
            options[4] = 0;


        options[5] = (argData.isFlagSet("-ast"))?1:0;

        options[6] = 0;
        if(argData.isFlagSet("-se"))
            options[6] = 1;

        if( CMDactionMode == 5 && argData.isFlagSet("-") )
            options[6] += 3;

        if(argData.isFlagSet("-sf"))
            options[6] = 2;

        if(argData.isFlagSet("-sv"))
            options[6] = 5;


        //IV flag - wenn -peb aktiv ist, wird er auf jeden Fall gesetzt
        if( argData.isFlagSet("-peb") )
            options[9] = 1;
        else
            options[9] = argData.isFlagSet("-civ")?true:false;

        //----------------------------------------OPTIONS ENDE

        slideIsRelative = argData.isFlagSet("-sir");

        //slideIsRelative ist an, wenn Chamfer aktiv ist
        if(chamferFlagSet+solidChamferFlagSet > 0)
            slideIsRelative = 1;

        if(CMDactionMode == 6)
            slideIsRelative = true;

        normalIsRelative = argData.isFlagSet("-nir");

        //slide soll automatisch auf  gesetzt werden, wenn -peb aktiv (dies entspricht einem slidewert von 1
        if( argData.isFlagSet("-peb") && edgeIDs.length() != 0)
            directSlide = 1;
        else
        {
            if(argData.isFlagSet("-slide"))

                argData.getFlagArgument("-slide",0,directSlide);
            else
                directSlide = 0.5;	//defaultValue
        }

    }


    }

    //undoIndo sammeln

    MSelectionMask tmpMask(MGlobal::componentSelectionMask());
    undoMask = tmpMask;



    /*
    	CallWindowProc(	(WNDPROC)(GetWindowLong(mayaWin, GWL_WNDPROC)),
    					mayaWin, WM_CLOSE, NULL, NULL);



    DWORD dwStyle = WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
    //MessageBox(mayaWin, "Help", "Whatever", MB_OK);
    HWND myWin = CreateWindowEx( 0,"MyFirstWin","Lala" , dwStyle, 0, 0,
    							300, 400,
    							mayaWin, NULL, NULL, NULL);

    ShowWindow(myWin, SW_SHOWNORMAL);
    SetFocus(myWin);
    UpdateWindow(myWin);
    */

    //checken ob makeHistory aus ist. Wenn ja, dann wieder an machen, weil maya sonst crashed
    int result;
    MGlobal::executeCommand( "constructionHistory -q -tgl", result );

    if(!result)
        MGlobal::executeCommand( "constructionHistory -tgl 1",false,false);




    meshDagPath.extendToShape();
//	Mesh von polyModifierCommand setzen
    setMeshNode(meshDagPath);



    switch(operationMode)
    {
    case 0:
    {
        //getEdgeComponents(sList);
        convertToEdges(sList, argData.isFlagSet("-peb") );

        // setCreateAnimCurves(false);//damit nicht versucht wird, auf dieser Node animCurves fuer tweak zu erstellen
        // Jetzt sind tweaks vonnten

        setModifierNodeType( BPT_InsertVtx::IVid );
        break;
    }
    case 1:
    {
        //	Komponenten herausfiltern und IntIDArrays schreiben

        //getEdgeComponents(sList);
        getVertComponents(sList);
        getPolyComponents(sList);

        setModifierNodeType( ByronsPolyToolsNode::id );
        break;
    }
    }

//	Aktion ausfuehren

    if(CMDactionMode == 0 || CMDactionMode == 4 || CMDactionMode == 5 || CMDactionMode == 6 || operationMode == 0)
    {

        MGlobal::executeCommand("setToolTo selectSuperContext",false,false);

        status = doModifyPoly();

        MFnDependencyNode depNodeFn(bptNode);
        setResult(depNodeFn.name());

        if( !(status == MS::kSuccess) )
        {
            MGlobal::displayError( "An error occoured." );
            MGlobal::displayError( status.errorString() );

        }
    }
    else
    {
//		Wenn mesh nicht veraendert wird, wird einfach so die Factory gerufen
        directModifier(meshDagPath.node());
        //setResult( "BPTOperation succeeded" );
    }


    //Command wird nur einmal verwendet, also muessen die Datenarrays auch m#keinen Speicher mehr verschwenden
    //.clear() wuerde sie nicht physisch loeschen
    polyIDs.setLength(0);
    edgeIDs.setLength(0);
    vertIDs.setLength(0);

//	return status;
    return MS::kSuccess;
}
示例#27
0
void MayaObject::getMeshData(MPointArray& points, MFloatVectorArray& normals, MFloatArray& uArray, MFloatArray& vArray, MIntArray& triPointIndices, MIntArray& triNormalIndices, MIntArray& triUvIndices, MIntArray& triMatIndices)
{

	MStatus stat;
	MObject meshObject = this->mobject;
	MMeshSmoothOptions options;
	MFnMesh tmpMesh(this->mobject, &stat);

	MFnMeshData meshData;
	MObject dataObject;
	MObject smoothedObj;

	// create smooth mesh if needed
	if (tmpMesh.findPlug("displaySmoothMesh").asBool())
	{
		stat = tmpMesh.getSmoothMeshDisplayOptions(options);
		if (stat)
		{
			if (!tmpMesh.findPlug("useSmoothPreviewForRender", false, &stat).asBool())
			{
				//Logging::debug(MString("useSmoothPreviewForRender turned off"));
				int smoothLevel = tmpMesh.findPlug("renderSmoothLevel", false, &stat).asInt();
				options.setDivisions(smoothLevel);
			}
			if (options.divisions() > 0)
			{
				dataObject = meshData.create();
				smoothedObj = tmpMesh.generateSmoothMesh(dataObject, &options, &stat);
				if (stat)
				{
					meshObject = smoothedObj;
				}
			}
		}
	}

	MFnMesh meshFn(meshObject, &stat);
	CHECK_MSTATUS(stat);
	MItMeshPolygon faceIt(meshObject, &stat);
	CHECK_MSTATUS(stat);

	meshFn.getPoints(points);
	meshFn.getNormals(normals, MSpace::kObject);
	meshFn.getUVs(uArray, vArray);

	uint numVertices = points.length();
	uint numNormals = normals.length();
	uint numUvs = uArray.length();

	//Logging::debug(MString("numVertices ") + numVertices);
	//Logging::debug(MString("numNormals ") + numNormals);
	//Logging::debug(MString("numUvs ") + numUvs);

	// some meshes may have no uv's
	// to avoid problems I add a default uv coordinate
	if (numUvs == 0)
	{
		Logging::warning(MString("Object has no uv's: ") + this->shortName);
		uArray.append(0.0);
		vArray.append(0.0);
	}
	for (uint nid = 0; nid < numNormals; nid++)
	{
		if (normals[nid].length() < 0.1f)
			Logging::warning(MString("Malformed normal in ") + this->shortName);
	}
	MPointArray triPoints;
	MIntArray triVtxIds;
	MIntArray faceVtxIds;
	MIntArray faceNormalIds;

	for (faceIt.reset(); !faceIt.isDone(); faceIt.next())
	{
		int faceId = faceIt.index();
		int numTris;
		faceIt.numTriangles(numTris);
		faceIt.getVertices(faceVtxIds);

		int perFaceShadingGroup = 0;
		if (this->perFaceAssignments.length() > 0)
			perFaceShadingGroup = this->perFaceAssignments[faceId];
		
		MIntArray faceUVIndices;
		
		faceNormalIds.clear();
		for (uint vtxId = 0; vtxId < faceVtxIds.length(); vtxId++)
		{
			faceNormalIds.append(faceIt.normalIndex(vtxId));
			int uvIndex;
			if (numUvs == 0)
			{
				faceUVIndices.append(0);
			}
			else{
				faceIt.getUVIndex(vtxId, uvIndex);
				//if (uvIndex > uArray.length())
				//	Logging::info(MString("-----------------> UV Problem!!! uvIndex ") + uvIndex + " > uvArray in object " + this->shortName);
				faceUVIndices.append(uvIndex);
			}
		}

		for (int triId = 0; triId < numTris; triId++)
		{
			int faceRelIds[3];
			faceIt.getTriangle(triId, triPoints, triVtxIds);

			for (uint triVtxId = 0; triVtxId < 3; triVtxId++)
			{
				for (uint faceVtxId = 0; faceVtxId < faceVtxIds.length(); faceVtxId++)
				{
					if (faceVtxIds[faceVtxId] == triVtxIds[triVtxId])
					{
						faceRelIds[triVtxId] = faceVtxId;
					}
				}
			}

			uint vtxId0 = faceVtxIds[faceRelIds[0]];
			uint vtxId1 = faceVtxIds[faceRelIds[1]];
			uint vtxId2 = faceVtxIds[faceRelIds[2]];
			uint normalId0 = faceNormalIds[faceRelIds[0]];
			uint normalId1 = faceNormalIds[faceRelIds[1]];
			uint normalId2 = faceNormalIds[faceRelIds[2]];
			uint uvId0 = faceUVIndices[faceRelIds[0]];
			uint uvId1 = faceUVIndices[faceRelIds[1]];
			uint uvId2 = faceUVIndices[faceRelIds[2]];

			triPointIndices.append(vtxId0);
			triPointIndices.append(vtxId1);
			triPointIndices.append(vtxId2);

			triNormalIndices.append(normalId0);
			triNormalIndices.append(normalId1);
			triNormalIndices.append(normalId2);

			triUvIndices.append(uvId0);
			triUvIndices.append(uvId1);
			triUvIndices.append(uvId2);

			triMatIndices.append(perFaceShadingGroup);

			//Logging::debug(MString("vtxIds ") + vtxId0 + " " + vtxId1 + " " + vtxId2);
			//Logging::debug(MString("nIds ") + normalId0 + " " + normalId1 + " " + normalId2);
			//Logging::debug(MString("uvIds ") + uvId0 + " " + uvId1 + " " + uvId2);
		}
	}

}
示例#28
0
MStatus mshUtil::doIt( const MArgList& args ) 
{
	MString objname, mcfname;
	MArgDatabase argData(syntax(), args);
	
	MSelectionList selList;
	MGlobal::getActiveSelectionList ( selList );

	if ( selList.length() < 2 ) {
		MGlobal:: displayError ( "Not sufficient selection!" );
		return MS::kSuccess;
	}
	
	MItSelectionList iter( selList );
	
	iter.reset();
	
	MDagPath meshPath;		
	iter.getDagPath( meshPath );
	
	meshPath.extendToShape();
	
	MObject meshObj = meshPath.node();

	MString surface = meshPath.partialPathName();
	
	MStatus status;
	MFnMesh meshFn(meshPath, &status );
	
	if(!status) {
		MGlobal:: displayError ( "Not sufficient selection!" );
		return MS::kSuccess;
	}
	
	MPointArray vxa;
	meshFn.getPoints (vxa, MSpace::kWorld);
	
	MPoint cenfrom(0.f, 0.f, 0.f);
	for(unsigned i=0; i<vxa.length(); i++) cenfrom += vxa[i];
	
	cenfrom = cenfrom/(float)vxa.length();
	
	iter.next();
	iter.getDagPath( meshPath );
	
	meshPath.extendToShape();
	
	MFnMesh mesh1Fn(meshPath, &status );
	
	if(!status) {
		MGlobal:: displayError ( "Not sufficient selection!" );
		return MS::kSuccess;
	}
	
	vxa.clear();
	mesh1Fn.getPoints (vxa, MSpace::kWorld);
	
	MPoint cento(0.f, 0.f, 0.f);
	for(unsigned i=0; i<vxa.length(); i++) cento += vxa[i];
	
	cento = cento/(float)vxa.length();
	
	MVector diff = cento - cenfrom;
	
	MDoubleArray res;
	res.append(diff.x);
	res.append(diff.y);
	res.append(diff.z);
	
	setResult ( res );
	
	/*	
	if ( !argData.isFlagSet("-i") || !argData.isFlagSet("-o") ) {
		//MGlobal::displayError( "No .obj or .mcf file specified to translate! Example: mshUtil -i filename.obj -o filename.mcf" );
		return MS::kSuccess;
	}
	else {
		argData.getFlagArgument("-i", 0, objname);
		argData.getFlagArgument("-o", 0, mcfname);
		
				
		return MS::kSuccess;
	}
*/
	return MS::kSuccess;
}
示例#29
0
// get the mesh informations from the current time and save it in the meshDataList
void MayaObject::addMeshData()
{
	MeshData mdata;

	if (this->hasBifrostVelocityChannel())
	{
		bool doMb = this->motionBlurred;
		std::shared_ptr<RenderGlobals> renderGlobals = MayaTo::getWorldPtr()->worldRenderGlobalsPtr;		
		doMb = doMb && renderGlobals->doMb;

		Logging::debug(MString("Found bifrost velocity data for object: ") + this->shortName);
		if ((this->meshDataList.size() == 2) || !doMb)
		{
			Logging::debug("Bifrost mesh already has two motion steps or mb is turned off for it -> skipping");
			return;
		}

		this->getMeshData(mdata.points, mdata.normals);

		// if we have a bifrost velocity channel I suppose this is a bifost mesh and there is no need to 
		// save the mesh motion steps because it has changing topology what does not work in most renderers
		// so we save only the very first motion step and derive the other steps from velocity channel.
		// and we simply produce two steps only because everything else would not make sense.

		MFnMesh meshFn(this->mobject);
		if (meshFn.hasColorChannels("bifrostVelocity"))
		{
			MColorArray colors;
			MString colorSetName = "bifrostVelocity";
			meshFn.getVertexColors(colors, &colorSetName);

			if (colors.length() == mdata.points.length())
			{
				for (uint ptId = 0; ptId < mdata.points.length(); ptId++)
				{
					MColor c = colors[ptId];
					MVector v = MVector(c.r, c.g, c.b);
					mdata.points[ptId] -= v * 0.5 / 24.0;
				}
				this->meshDataList.push_back(mdata);
				for (uint ptId = 0; ptId < mdata.points.length(); ptId++)
				{
					MColor c = colors[ptId];
					MVector v = MVector(c.r, c.g, c.b);
					mdata.points[ptId] += v * 0.5 / 24.0;
				}
				this->meshDataList.push_back(mdata);
			}
		}else{
			Logging::debug("Bifrost mesh has no velocity data, no motionblur.");
			if (this->meshDataList.size() == 0)
				this->meshDataList.push_back(mdata);
		}
	}
	else{
		this->getMeshData(mdata.points, mdata.normals);
		int np = mdata.points.length();
		this->meshDataList.push_back(mdata);

		for (auto md : this->meshDataList)
		{
			np = md.points.length();
		}
	}

}
示例#30
0
// #### rebuildHbrMeshIfNeeded
//
//      If the topology of the mesh changes, or any attributes that affect
//      how the mesh is computed the original HBR needs to be rebuilt
//      which will trigger a rebuild of the FAR mesh and subsequent buffers.
//
void
OsdMeshData::rebuildHbrMeshIfNeeded(OpenSubdivShader *shader)
{
    MStatus status = MS::kSuccess;

    if (!_meshTopoDirty && !shader->getHbrMeshDirty())
        return;

    MFnMesh meshFn(_meshDagPath);

    // Cache attribute values
    _level      = shader->getLevel();
    _kernel     = shader->getKernel();
    _adaptive   = shader->isAdaptive();
    _uvSet      = shader->getUVSet();

    // Get Maya vertex topology and crease data
    MIntArray vertexCount;
    MIntArray vertexList;
    meshFn.getVertices(vertexCount, vertexList);

    MUintArray edgeIds;
    MDoubleArray edgeCreaseData;
    meshFn.getCreaseEdges(edgeIds, edgeCreaseData);

    MUintArray vtxIds;
    MDoubleArray vtxCreaseData;
    meshFn.getCreaseVertices(vtxIds, vtxCreaseData);

    if (vertexCount.length() == 0) return;

    // Copy Maya vectors into std::vectors
    std::vector<int> numIndices(&vertexCount[0], &vertexCount[vertexCount.length()]);
    std::vector<int> faceIndices(&vertexList[0], &vertexList[vertexList.length()]);
    std::vector<int> vtxCreaseIndices(&vtxIds[0], &vtxIds[vtxIds.length()]);
    std::vector<double> vtxCreases(&vtxCreaseData[0], &vtxCreaseData[vtxCreaseData.length()]);
    std::vector<double> edgeCreases(&edgeCreaseData[0], &edgeCreaseData[edgeCreaseData.length()]);

    // Edge crease index is stored as pairs of vertex ids
    int nEdgeIds = edgeIds.length();
    std::vector<int> edgeCreaseIndices;
    edgeCreaseIndices.resize(nEdgeIds*2);
    for (int i = 0; i < nEdgeIds; ++i) {
        int2 vertices;
        status = meshFn.getEdgeVertices(edgeIds[i], vertices);
        if (status.error()) {
            MERROR(status, "OpenSubdivShader: Can't get edge vertices");
            continue;
        }
        edgeCreaseIndices[i*2] = vertices[0];
        edgeCreaseIndices[i*2+1] = vertices[1];
    }

    // Convert attribute enums to HBR enums (this is why the enums need to match)
    HbrMeshUtil::SchemeType hbrScheme = (HbrMeshUtil::SchemeType) shader->getScheme();
    OsdHbrMesh::InterpolateBoundaryMethod hbrInterpBoundary = 
            (OsdHbrMesh::InterpolateBoundaryMethod) shader->getInterpolateBoundary();
    OsdHbrMesh::InterpolateBoundaryMethod hbrInterpUVBoundary = 
            (OsdHbrMesh::InterpolateBoundaryMethod) shader->getInterpolateUVBoundary();


    // clear any existing face-varying descriptor
    if (_fvarDesc) {
        delete _fvarDesc;
        _fvarDesc = NULL;
    }

    // read UV data from maya and build per-face per-vert list of UVs for HBR face-varying data
    std::vector< float > uvList;
    status = buildUVList( meshFn, uvList );
    if (! status.error()) {
        // Create face-varying data descriptor.  The memory required for indices
        // and widths needs to stay alive as the HBR library only takes in the
        // pointers and assumes the client will maintain the memory so keep _fvarDesc
        // around as long as _hbrmesh is around.
        int fvarIndices[] = { 0, 1 };
        int fvarWidths[] = { 1, 1 };
        _fvarDesc = new FVarDataDesc( 2, fvarIndices, fvarWidths, 2, hbrInterpUVBoundary );
    }

    if (_fvarDesc && hbrScheme != HbrMeshUtil::kCatmark) {
        MGlobal::displayWarning("Face-varying not yet supported for Loop/Bilinear, using Catmull-Clark");
        hbrScheme = HbrMeshUtil::kCatmark;
    }

    // Convert Maya mesh to internal HBR representation
    _hbrmesh = ConvertToHBR(meshFn.numVertices(), numIndices, faceIndices,
                            vtxCreaseIndices, vtxCreases,
                            std::vector<int>(), std::vector<float>(),
                            edgeCreaseIndices, edgeCreases,
                            hbrInterpBoundary, 
                            hbrScheme,
                            false,                      // no ptex
                            _fvarDesc, 
                            _fvarDesc?&uvList:NULL);    // yes fvar (if have UVs)

    // note: GL function can't be used in prepareForDraw API.
    _needsInitializeMesh = true;

    // Mesh topology data is up to date
    _meshTopoDirty = false;
    shader->setHbrMeshDirty(false);
}