MStatus GetAdjacency(MDagPath& pathMesh, std::vector<std::set<int> >& adjacency) { MStatus status; // Get mesh adjacency. The adjacency will be all vertex ids on the connected faces. MItMeshVertex itVert(pathMesh, MObject::kNullObj, &status); CHECK_MSTATUS_AND_RETURN_IT(status); MFnMesh fnMesh(pathMesh, &status); CHECK_MSTATUS_AND_RETURN_IT(status); adjacency.resize(itVert.count()); for (; !itVert.isDone(); itVert.next()) { MIntArray faces; status = itVert.getConnectedFaces(faces); CHECK_MSTATUS_AND_RETURN_IT(status); adjacency[itVert.index()].clear(); // Put the vertex ids in a set to avoid duplicates for (unsigned int j = 0; j < faces.length(); ++j) { MIntArray vertices; fnMesh.getPolygonVertices(faces[j], vertices); for (unsigned int k = 0; k < vertices.length(); ++k) { if (vertices[k] != itVert.index()) { adjacency[itVert.index()].insert(vertices[k]); } } } } return MS::kSuccess; }
void TestDeformer::__debugMeshInfo(const char* msg, MObject &meshMobj) { #ifdef _DEBUG MStatus status; MFnMesh fnMesh(meshMobj, &status); CHECK_MSTATUS(status); __debug("%s(), fnMesh.fullPathName=%s", msg, fnMesh.fullPathName().asChar()); __debug("%s(), fnMesh.name=%s", msg, fnMesh.name().asChar()); MDagPath path; CHECK_MSTATUS(fnMesh.getPath(path)); __debug("%s(), path=%s", msg, path.fullPathName().asChar()); MDagPath dagpath = fnMesh.dagPath(&status); CHECK_MSTATUS(status); __debug("%s(), dagpath=%s", msg, dagpath.fullPathName().asChar()); MFnDependencyNode fnDNode(meshMobj, &status); CHECK_MSTATUS(status);// __debug("%s(), name=%s", msg, fnDNode.name().asChar()); MFnDagNode fnDagNode(meshMobj, &status); CHECK_MSTATUS(status);// MDagPath path2; CHECK_MSTATUS(fnDagNode.getPath(path2));// __debug("%s(), path2=%s", msg, path2.fullPathName().asChar()); MDagPath dagpath2 = fnDagNode.dagPath(&status); CHECK_MSTATUS(status);// __debug("%s(), dagpath2=%s", msg, dagpath2.fullPathName().asChar()); #endif }
// virtual // Tells maya that color per vertex will be needed. int hwColorPerVertexShader::normalsPerVertex() { unsigned int numNormals = mNormalsPerVertex; MStringArray setNames; const MDagPath & path = currentPath(); if (path.hasFn( MFn::kMesh ) ) { // Check the # of uvsets. If no uvsets // then can't return tangent or binormals // // MGlobal::displayInfo( path.fullPathName() ); MFnMesh fnMesh( path.node() ); if (fnMesh.numUVSets() == 0) { // Put out a warnnig if we're asking for too many uvsets. MString dispWarn("Asking for more uvsets then available for shape: "); MString pathName = path.fullPathName(); dispWarn = dispWarn + pathName; MGlobal::displayWarning( dispWarn ); numNormals = (mNormalsPerVertex > 1 ? 1 : 0); } } return numNormals; }
MStatus MVGMesh::setPoint(const int vertexId, const MPoint& point) const { MStatus status; MFnMesh fnMesh(_object, &status); status = fnMesh.setPoint(vertexId, point, MSpace::kWorld); CHECK_RETURN_STATUS(status); return status; }
int MVGMesh::getPolygonsCount() const { MStatus status; MFnMesh fnMesh(_object, &status); CHECK(status); int count = fnMesh.numPolygons(&status); CHECK(status); return count; }
MStatus MVGMesh::getPoints(MPointArray& pointArray) const { MStatus status; MFnMesh fnMesh(_object, &status); CHECK_RETURN_STATUS(status); status = fnMesh.getPoints(pointArray, MSpace::kWorld); CHECK_RETURN_STATUS(status) return status; }
bool MVGMesh::deletePolygon(const int index) const { MStatus status; MFnMesh fnMesh(_object, &status); CHECK_RETURN_VARIABLE(status, false) status = fnMesh.deleteFace(index); CHECK_RETURN_VARIABLE(status, false) return true; }
int MVGMesh::getVerticesCount() const { MStatus status; MFnMesh fnMesh(_object, &status); CHECK(status); int count = fnMesh.numVertices(&status); CHECK(status); return count; }
MStatus MVGMesh::getPolygonVertices(const int polygonId, MIntArray& vertexList) const { MStatus status; MFnMesh fnMesh(_object, &status); CHECK_RETURN_STATUS(status); status = fnMesh.getPolygonVertices(polygonId, vertexList); CHECK_RETURN_STATUS(status) return status; }
MStatus MVGMesh::getPoint(int vertexId, MPoint& point) const { MStatus status; assert(_dagpath.isValid()); MFnMesh fnMesh(_dagpath, &status); status = fnMesh.getPoint(vertexId, point, MSpace::kWorld); CHECK_RETURN_STATUS(status) return status; }
bool getObjectShadingGroups(const MDagPath& shapeObjectDP, MObject& shadingGroup) { // if obj is a light, simply return the mobject if (shapeObjectDP.hasFn(MFn::kLight)) shadingGroup = shapeObjectDP.node(); if (shapeObjectDP.hasFn(MFn::kMesh)) { // Find the Shading Engines Connected to the SourceNode MFnMesh fnMesh(shapeObjectDP.node()); // A ShadingGroup will have a MFnSet MObjectArray sets, comps; fnMesh.getConnectedSetsAndMembers(shapeObjectDP.instanceNumber(), sets, comps, true); // Each set is a Shading Group. Loop through them for (unsigned int i = 0; i < sets.length(); ++i) { shadingGroup = sets[i]; return true; } } if (shapeObjectDP.hasFn(MFn::kNurbsSurface)||shapeObjectDP.hasFn(MFn::kParticle)||shapeObjectDP.hasFn(MFn::kNParticle)) { MObject instObjGroupsAttr; if (shapeObjectDP.hasFn(MFn::kNurbsSurface)) { MFnNurbsSurface fnNurbs(shapeObjectDP.node()); instObjGroupsAttr = fnNurbs.attribute("instObjGroups"); } if (shapeObjectDP.hasFn(MFn::kParticle)||shapeObjectDP.hasFn(MFn::kNParticle)) { MFnParticleSystem fnPart(shapeObjectDP.node()); instObjGroupsAttr = fnPart.attribute("instObjGroups"); } MPlug instPlug(shapeObjectDP.node(), instObjGroupsAttr); // Get the instance that our node is referring to; // In other words get the Plug for instObjGroups[intanceNumber]; MPlug instPlugElem = instPlug.elementByLogicalIndex(shapeObjectDP.instanceNumber()); // Find the ShadingGroup plugs that we are connected to as Source MPlugArray SGPlugArray; instPlugElem.connectedTo(SGPlugArray, false, true); // Loop through each ShadingGroup Plug for (unsigned int i=0; i < SGPlugArray.length(); ++i) { shadingGroup = SGPlugArray[i].node(); return true; } } return false; }
bool MVGMesh::addPolygon(const MPointArray& pointArray, int& index) const { MStatus status; MFnMesh fnMesh(_object, &status); if(pointArray.length() < 3) return false; fnMesh.addPolygon(pointArray, index, true, kMFnMeshPointTolerance, MObject::kNullObj, &status); CHECK_RETURN_VARIABLE(status, false) return true; }
void printMaterials(const MDagPath& dagPath) { MFnMesh fnMesh(dagPath); unsigned instanceNumber = dagPath.instanceNumber(); MObjectArray sets; MObjectArray comps; fnMesh.getConnectedSetsAndMembers( instanceNumber, sets, comps, true ); // Print Material Names for(unsigned int i = 0; i < sets.length(); ++i) { MFnDependencyNode fnDepSGNode(sets[i]); std::cout << fnDepSGNode.name() << std::endl; } }
MStatus RippleDeformer::deform(MDataBlock& dataBlock, MItGeometry& itGeo, const MMatrix& localToWorldMatrix, unsigned int geomIndex) { MStatus status; //get attriubtes as a datahandle float env = dataBlock.inputValue(envelope).asFloat(); float amplitude = dataBlock.inputValue(aAmplitude).asFloat(); float displace = dataBlock.inputValue(aDisplace).asFloat(); //get the mesh //retrieve the handle to the input attribute MArrayDataHandle hInput = dataBlock.outputArrayValue(input, &status); CHECK_MSTATUS_AND_RETURN_IT(status); //get the input array index handle status = hInput.jumpToElement(geomIndex); //get the handle of geomIndex attribute MDataHandle hInputElement = hInput.outputValue(&status); //Get the MObject of the input geometry of geomindex MObject oInputGeom = hInputElement.child(inputGeom).asMesh(); MFnMesh fnMesh(oInputGeom, &status); CHECK_MSTATUS_AND_RETURN_IT(status); if (oInputGeom.isNull()) { return MS::kSuccess; } MFloatVectorArray normals; fnMesh.getVertexNormals(false, normals); MPoint pointPos; float weight; for (; !itGeo.isDone(); itGeo.next()) { //get current point position pointPos = itGeo.position(); weight = weightValue(dataBlock, geomIndex, itGeo.index()); pointPos.x = pointPos.x + sin(itGeo.index() + displace) * amplitude * normals[itGeo.index()].x * weight * env; pointPos.y = pointPos.y + sin(itGeo.index() + displace) * amplitude * normals[itGeo.index()].y * weight * env; pointPos.z = pointPos.z + sin(itGeo.index() + displace) * amplitude * normals[itGeo.index()].z * weight * env; //setPosition itGeo.setPosition(pointPos); } return MS::kSuccess; }
MStatus MVGMesh::setBlindData(const int vertexId, std::vector<ClickedCSPosition>& clickedCSPositions) const { MStatus status; MFnMesh fnMesh(_object, &status); CHECK_RETURN_STATUS(status); char* charData = reinterpret_cast<char*>(clickedCSPositions.data()); const int binarySize = clickedCSPositions.size() * sizeof(ClickedCSPosition); CHECK_RETURN_STATUS( fnMesh.setIntBlindData(vertexId, MFn::kMeshVertComponent, _blindDataID, "size", binarySize)) CHECK_RETURN_STATUS(fnMesh.setBinaryBlindData(vertexId, MFn::kMeshVertComponent, _blindDataID, "data", charData, binarySize)) return status; }
MStatus MVGMesh::setPoints(const MIntArray& verticesIds, const MPointArray& points) const { MStatus status; assert(verticesIds.length() == points.length()); assert(_dagpath.isValid()); MFnMesh fnMesh(_dagpath, &status); for(int i = 0; i < verticesIds.length(); ++i) { status = fnMesh.setPoint(verticesIds[i], points[i], MSpace::kWorld); CHECK_RETURN_STATUS(status); } fnMesh.syncObject(); return status; }
void CXRayObjectExport::buildEdgeTable( MDagPath& mesh ) { //. if ( !smoothing ) return; // Create our edge lookup table and initialize all entries to NULL // MFnMesh fnMesh( mesh ); edgeTableSize = fnMesh.numVertices(); edgeTable = xr_alloc<SXREdgeInfoPtr>(edgeTableSize); ZeroMemory(edgeTable,edgeTableSize*sizeof(int)); // Add entries, for each edge, to the lookup table // MItMeshEdge eIt( mesh ); for ( ; !eIt.isDone(); eIt.next() ) { bool smooth = eIt.isSmooth(); addEdgeInfo( eIt.index(0), eIt.index(1), smooth ); } // Fill in referenced polygons // MItMeshPolygon pIt( mesh ); for ( ; !pIt.isDone(); pIt.next() ) { int pvc = pIt.polygonVertexCount(); for ( int v=0; v<pvc; v++ ) { int a = pIt.vertexIndex( v ); int b = pIt.vertexIndex( v==(pvc-1) ? 0 : v+1 ); SXREdgeInfoPtr elem = findEdgeInfo( a, b ); if ( NULL != elem ) { int edgeId = pIt.index(); if ( INVALID_ID == elem->polyIds[0] ) { elem->polyIds[0] = edgeId; } else { elem->polyIds[1] = edgeId; } } } } CreateSmoothingGroups( fnMesh ); }
void vixo_hairCacheExport::initBasicStepInfo(int vid,MObject & staticMesh,map<int,inVertexBasicInfo>& inVIDMapInVertexDataBase) { inVertexBasicInfo ele; inVIDMapInVertexDataBase.insert(pair<int,inVertexBasicInfo>(vid,ele)); map<int,inVertexBasicInfo>::iterator iter=inVIDMapInVertexDataBase.find(vid); iter->second.stepVertex.resize(MAXSTEP); forInVertexBasicInfo subele; subele.vertexID=vid; subele.distance=0; iter->second.stepVertex[0].insert(subele); MItMeshVertex iterVertex4Record(staticMesh); MIntArray tempConnectedVertex; int prevIndex; MFnMesh fnMesh(staticMesh); MPointArray allPoints; fnMesh.getPoints(allPoints,MSpace::kObject); set<int> checkedVertex; checkedVertex.insert(vid); set<forInVertexBasicInfo>::iterator lastStepSetIter; for(int step=1;step<MAXSTEP;step++) { for(lastStepSetIter=iter->second.stepVertex[step-1].begin();lastStepSetIter!=iter->second.stepVertex[step-1].end();lastStepSetIter++) { iterVertex4Record.setIndex(lastStepSetIter->vertexID,prevIndex); iterVertex4Record.getConnectedVertices(tempConnectedVertex); for(int j=0;j<tempConnectedVertex.length();j++) { if(checkedVertex.count(tempConnectedVertex[j])<=0) { forInVertexBasicInfo subeleTemp; subeleTemp.vertexID=tempConnectedVertex[j]; subeleTemp.distance=allPoints[vid].distanceTo(allPoints[subeleTemp.vertexID]); iter->second.stepVertex[step].insert(subeleTemp); checkedVertex.insert(tempConnectedVertex[j]); } } } } }
MStatus tm_randPoint::undoIt() { if(helpMode) return MS::kSuccess; if(selVtxMode) { MSelectionList curSel; MGlobal::getActiveSelectionList( curSel); MItSelectionList iter( curSel, MFn::kMeshVertComponent); MObject component; MDagPath selVtx_dagPath; int vtxCount = 0; for ( ; !iter.isDone(); iter.next() ) { iter.getDagPath(selVtx_dagPath, component); MItMeshVertex vertexIter( selVtx_dagPath, component ); for ( ; !vertexIter.isDone(); vertexIter.next() ) { vertexIter.setPosition( oldPointsArrays[0][vtxCount], MSpace::kObject ); vtxCount++; } } } else { int num_meshes = res_MDagPathArray.length(); for( int i = 0; i < num_meshes; i++ ) { MDagPath dagPath = res_MDagPathArray[i]; MObject node; node = dagPath.node(); MFnDependencyNode fnNode( node ); MStatus polyStatus; MFnMesh fnMesh( node, &polyStatus ); if( polyStatus == MS::kSuccess ) { MStatus status; status = fnMesh.setPoints( oldPointsArrays[i]); if (!status){status.perror("### error setting point ::undoIt()");return status;} } } } return MS::kSuccess; }
MStatus MVGMesh::getBlindData(const int vertexId, std::vector<ClickedCSPosition>& clickedCSPositions) const { MStatus status; MFnMesh fnMesh(_object, &status); CHECK_RETURN_STATUS(status); if(!fnMesh.hasBlindData(MFn::kMeshVertComponent)) return MS::kFailure; if(!fnMesh.hasBlindDataComponentId(vertexId, MFn::kMeshVertComponent, _blindDataID)) return MS::kFailure; int binarySize; CHECK_RETURN_STATUS( fnMesh.getIntBlindData(vertexId, MFn::kMeshVertComponent, _blindDataID, "size", binarySize)) MString stringData; CHECK_RETURN_STATUS(fnMesh.getBinaryBlindData(vertexId, MFn::kMeshVertComponent, _blindDataID, "data", stringData)) const char* binData = stringData.asChar(binarySize); binaryToVectorData(binData, binarySize, clickedCSPositions); return status; }
// virtual // Tells maya that color per vertex will be needed. int hwColorPerVertexShader::colorsPerVertex() { int returnVal = 0; // Going to be displaying false coloring, // so skip getting internal colors. if (mNormalsPerVertex) return 0; else { const MDagPath & path = currentPath(); if (path.hasFn( MFn::kMesh ) ) { MFnMesh fnMesh( path.node() ); unsigned int numColorSets = fnMesh.numColorSets(); if (numColorSets < 2) returnVal = numColorSets; else returnVal = 2; } } return returnVal; }
bool DX11ViewportRenderer::drawSurface( const MDagPath &dagPath, bool active, bool templated) { bool drewSurface = false; if ( !dagPath.hasFn( MFn::kMesh )) { MMatrix matrix = dagPath.inclusiveMatrix(); MFnDagNode dagNode(dagPath); MBoundingBox box = dagNode.boundingBox(); float color[3] = {0.6f, 0.3f, 0.0f}; if (active) { color[0] = 1.0f; color[1] = 1.0f; color[2] = 1.0f; } else if (templated) { color[0] = 1.0f; color[1] = 0.686f; color[2] = 0.686f; } drawBounds( matrix, box, color); return true; } if ( dagPath.hasFn( MFn::kMesh )) { MMatrix matrix = dagPath.inclusiveMatrix(); MFnDagNode dagNode(dagPath); // Look for any hardware shaders which can draw D3D first. // bool drewWithHwShader = false; { MFnMesh fnMesh(dagPath); MObjectArray sets; MObjectArray comps; unsigned int instanceNum = dagPath.instanceNumber(); if (!fnMesh.getConnectedSetsAndMembers(instanceNum, sets, comps, true)) MGlobal::displayError("ERROR : MFnMesh::getConnectedSetsAndMembers"); for ( unsigned i=0; i<sets.length(); i++ ) { MObject set = sets[i]; MObject comp = comps[i]; MStatus status; MFnSet fnSet( set, &status ); if (status == MS::kFailure) { MGlobal::displayError("ERROR: MFnSet::MFnSet"); continue; } MObject shaderNode = findShader(set); if (shaderNode != MObject::kNullObj) { MPxHardwareShader * hwShader = MPxHardwareShader::getHardwareShaderPtr( shaderNode ); if (hwShader) { const MRenderProfile & profile = hwShader->profile(); if (profile.hasRenderer( MRenderProfile::kMayaD3D)) { // Render a Maya D3D hw shader here.... //printf("Found a D3D hw shader\n"); //drewWithHwShader = true; } } } } } // Get the geometry buffers for this bad boy and render them D3DGeometry* Geometry = m_resourceManager.getGeometry( dagPath, m_pD3DDevice); if( Geometry) { // Transform from object to world space // XMMATRIX objectToWorld = XMMATRIX ( (float)matrix.matrix[0][0], (float)matrix.matrix[0][1], (float)matrix.matrix[0][2], (float)matrix.matrix[0][3], (float)matrix.matrix[1][0], (float)matrix.matrix[1][1], (float)matrix.matrix[1][2], (float)matrix.matrix[1][3], (float)matrix.matrix[2][0], (float)matrix.matrix[2][1], (float)matrix.matrix[2][2], (float)matrix.matrix[2][3], (float)matrix.matrix[3][0], (float)matrix.matrix[3][1], (float)matrix.matrix[3][2], (float)matrix.matrix[3][3] ); FixedFunctionConstants cb; if (!drewWithHwShader) { // Get material properties for shader associated with mesh // // 1. Try to draw with the sample internal programmable shader bool drewGeometryWithShader = false; // 2. Draw with fixed function shader if (!drewGeometryWithShader) { // Set up a default material, just in case there is none. // float diffuse[3]; if (active) { if (templated) { m_pD3DDeviceCtx->RSSetState( m_pWireframeRS ); diffuse[0] = 1.0f; diffuse[1] = 0.686f; diffuse[2] = 0.686f; } else { m_pD3DDeviceCtx->RSSetState( m_pNormalRS ); diffuse[0] = 0.6f; diffuse[1] = 0.6f; diffuse[2] = 0.6f; } } else { if (templated) { m_pD3DDeviceCtx->RSSetState( m_pWireframeRS ); diffuse[0] = 1.0f; diffuse[1] = 0.686f; diffuse[2] = 0.686f; } else { m_pD3DDeviceCtx->RSSetState( m_pNormalRS ); diffuse[0] = 0.5f; diffuse[1] = 0.5f; diffuse[2] = 0.5f; } } // Set constant buffer XMVECTOR det; cb.wvIT = XMMatrixInverse( &det, objectToWorld * m_currentViewMatrix ); cb.wvp = XMMatrixTranspose( objectToWorld * m_currentViewMatrix * m_currentProjectionMatrix ); cb.wv = XMMatrixTranspose( objectToWorld * m_currentViewMatrix ); cb.lightDir = XMFLOAT4( 0.0f, 0.0f, 1.0f, 0.0f ); cb.lightColor = XMFLOAT4( 1.0f, 1.0f, 1.0f, 0.0f ); cb.ambientLight = XMFLOAT4( 0.2f, 0.2f, 0.2f, 0.0f ); cb.diffuseMaterial = XMFLOAT4( diffuse[0], diffuse[1], diffuse[2], 0.0f ); cb.specularColor = XMFLOAT4( 0.2f, 0.2f, 0.2f, 0.0f ); cb.diffuseCoeff = 1.0f; cb.shininess = 16.0f; cb.transparency = 1.0f; m_pD3DDeviceCtx->UpdateSubresource( m_pFixedFunctionConstantBuffer, 0, NULL, &cb, 0, 0 ); // get shader SurfaceEffectItemList::const_iterator it = m_resourceManager.getSurfaceEffectItemList().find( "Maya_fixedFunction" ); if ( it == m_resourceManager.getSurfaceEffectItemList().end() ) return false; const SurfaceEffectItem* sei = it->second; // bind shaders m_pD3DDeviceCtx->VSSetShader( sei->fVertexShader, NULL, 0 ); m_pD3DDeviceCtx->VSSetConstantBuffers( 0, 1, &m_pFixedFunctionConstantBuffer ); m_pD3DDeviceCtx->IASetInputLayout( sei->fInputLayout ); m_pD3DDeviceCtx->PSSetShader( sei->fPixelShader, NULL, 0 ); m_pD3DDeviceCtx->PSSetConstantBuffers( 0, 1, &m_pFixedFunctionConstantBuffer ); Geometry->Render( m_pD3DDeviceCtx ); drewSurface = true; } } // Draw wireframe on top // if ( drewSurface && active ) { bool drawActiveWithBounds = false; if (drawActiveWithBounds) { MBoundingBox box = dagNode.boundingBox(); float color[3] = {1.0f, 1.0f, 1.0f}; drawBounds( matrix, box, color ); } else { cb.lightColor = XMFLOAT4( 0.0f, 0.0f, 0.0f, 0.0f ); cb.ambientLight = XMFLOAT4( 1.0f, 1.0f, 1.0f, 0.0f ); cb.diffuseMaterial = XMFLOAT4( 1.0f, 1.0f, 1.0f, 0.0f ); cb.specularColor = XMFLOAT4( 0.0f, 0.0f, 0.0f, 0.0f ); m_pD3DDeviceCtx->UpdateSubresource( m_pFixedFunctionConstantBuffer, 0, NULL, &cb, 0, 0 ); m_pD3DDeviceCtx->RSSetState( m_pWireframeRS ); Geometry->Render( m_pD3DDeviceCtx ); } } } // If Geometry } return drewSurface; }
MStatus AlembicNode::compute(const MPlug & plug, MDataBlock & dataBlock) { MStatus status; // update the frame number to be imported MDataHandle speedHandle = dataBlock.inputValue(mSpeedAttr, &status); double speed = speedHandle.asDouble(); MDataHandle offsetHandle = dataBlock.inputValue(mOffsetAttr, &status); double offset = offsetHandle.asDouble(); MDataHandle timeHandle = dataBlock.inputValue(mTimeAttr, &status); MTime t = timeHandle.asTime(); double inputTime = t.as(MTime::kSeconds); double fps = getFPS(); // scale and offset inputTime. inputTime = computeAdjustedTime(inputTime, speed, offset/fps); // this should be done only once per file if (mFileInitialized == false) { mFileInitialized = true; MDataHandle dataHandle = dataBlock.inputValue(mAbcFileNameAttr); MFileObject fileObject; fileObject.setRawFullName(dataHandle.asString()); MString fileName = fileObject.resolvedFullName(); // TODO, make sure the file name, or list of files create a valid // Alembic IArchive // initialize some flags for plug update mSubDInitialized = false; mPolyInitialized = false; // When an alembic cache will be imported at the first time using // AbcImport, we need to set mIncludeFilterAttr (filterHandle) to be // mIncludeFilterString for later use. When we save a maya scene(.ma) // mIncludeFilterAttr will be saved. Then when we load the saved // .ma file, mIncludeFilterString will be set to be mIncludeFilterAttr. MDataHandle includeFilterHandle = dataBlock.inputValue(mIncludeFilterAttr, &status); MString& includeFilterString = includeFilterHandle.asString(); if (mIncludeFilterString.length() > 0) { includeFilterHandle.set(mIncludeFilterString); dataBlock.setClean(mIncludeFilterAttr); } else if (includeFilterString.length() > 0) { mIncludeFilterString = includeFilterString; } MDataHandle excludeFilterHandle = dataBlock.inputValue(mExcludeFilterAttr, &status); MString& excludeFilterString = excludeFilterHandle.asString(); if (mExcludeFilterString.length() > 0) { excludeFilterHandle.set(mExcludeFilterString); dataBlock.setClean(mExcludeFilterAttr); } else if (excludeFilterString.length() > 0) { mExcludeFilterString = excludeFilterString; } MFnDependencyNode dep(thisMObject()); MPlug allSetsPlug = dep.findPlug("allColorSets"); CreateSceneVisitor visitor(inputTime, !allSetsPlug.isNull(), MObject::kNullObj, CreateSceneVisitor::NONE, "", mIncludeFilterString, mExcludeFilterString); { mData.getFrameRange(mSequenceStartTime, mSequenceEndTime); MDataHandle startFrameHandle = dataBlock.inputValue(mStartFrameAttr, &status); startFrameHandle.set(mSequenceStartTime*fps); MDataHandle endFrameHandle = dataBlock.inputValue(mEndFrameAttr, &status); endFrameHandle.set(mSequenceEndTime*fps); } } // Retime MDataHandle cycleHandle = dataBlock.inputValue(mCycleTypeAttr, &status); short playType = cycleHandle.asShort(); inputTime = computeRetime(inputTime, mSequenceStartTime, mSequenceEndTime, playType); clamp<double>(mSequenceStartTime, mSequenceEndTime, inputTime); // update only when the time lapse is big enough if (fabs(inputTime - mCurTime) > 0.00001) { mOutRead = std::vector<bool>(mOutRead.size(), false); mCurTime = inputTime; } if (plug == mOutPropArrayAttr) { if (mOutRead[0]) { dataBlock.setClean(plug); return MS::kSuccess; } mOutRead[0] = true; unsigned int propSize = static_cast<unsigned int>(mData.mPropList.size()); if (propSize > 0) { MArrayDataHandle outArrayHandle = dataBlock.outputValue( mOutPropArrayAttr, &status); unsigned int outHandleIndex = 0; MDataHandle outHandle; // for all of the nodes with sampled attributes for (unsigned int i = 0; i < propSize; i++) { // only use the handle if it matches the index. // The index wont line up in the sparse case so we // can just skip that element. if (outArrayHandle.elementIndex() == outHandleIndex++) { outHandle = outArrayHandle.outputValue(); } else { continue; } if (mData.mPropList[i].mArray.valid()) { readProp(mCurTime, mData.mPropList[i].mArray, outHandle); } else if (mData.mPropList[i].mScalar.valid()) { // for visibility only if (mData.mPropList[i].mScalar.getName() == Alembic::AbcGeom::kVisibilityPropertyName) { Alembic::Util::int8_t visVal = 1; mData.mPropList[i].mScalar.get(&visVal, Alembic::Abc::ISampleSelector(mCurTime, Alembic::Abc::ISampleSelector::kNearIndex )); outHandle.setGenericBool(visVal != 0, false); } else { // for all scalar props readProp(mCurTime, mData.mPropList[i].mScalar, outHandle); } } outArrayHandle.next(); } outArrayHandle.setAllClean(); } } else if (plug == mOutTransOpArrayAttr ) { if (mOutRead[1]) { dataBlock.setClean(plug); return MS::kSuccess; } mOutRead[1] = true; unsigned int xformSize = static_cast<unsigned int>(mData.mXformList.size()); if (xformSize > 0) { MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutTransOpArrayAttr, &status); MPlug arrayPlug(thisMObject(), mOutTransOpArrayAttr); MDataHandle outHandle; unsigned int outHandleIndex = 0; for (unsigned int i = 0; i < xformSize; i++) { std::vector<double> sampleList; if (mData.mIsComplexXform[i]) { readComplex(mCurTime, mData.mXformList[i], sampleList); } else { Alembic::AbcGeom::XformSample samp; read(mCurTime, mData.mXformList[i], sampleList, samp); } unsigned int sampleSize = (unsigned int)sampleList.size(); for (unsigned int j = 0; j < sampleSize; j++) { // only use the handle if it matches the index. // The index wont line up in the sparse case so we // can just skip that element. if (outArrayHandle.elementIndex() == outHandleIndex++) { outHandle = outArrayHandle.outputValue(&status); } else continue; outArrayHandle.next(); outHandle.set(sampleList[j]); } } outArrayHandle.setAllClean(); } } else if (plug == mOutLocatorPosScaleArrayAttr ) { if (mOutRead[8]) { dataBlock.setClean(plug); return MS::kSuccess; } mOutRead[8] = true; unsigned int locSize = static_cast<unsigned int>(mData.mLocList.size()); if (locSize > 0) { MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutLocatorPosScaleArrayAttr, &status); MPlug arrayPlug(thisMObject(), mOutLocatorPosScaleArrayAttr); MDataHandle outHandle; unsigned int outHandleIndex = 0; for (unsigned int i = 0; i < locSize; i++) { std::vector< double > sampleList; read(mCurTime, mData.mLocList[i], sampleList); unsigned int sampleSize = (unsigned int)sampleList.size(); for (unsigned int j = 0; j < sampleSize; j++) { // only use the handle if it matches the index. // The index wont line up in the sparse case so we // can just skip that element. if (outArrayHandle.elementIndex() == outHandleIndex++) { outHandle = outArrayHandle.outputValue(&status); } else continue; outArrayHandle.next(); outHandle.set(sampleList[j]); } } outArrayHandle.setAllClean(); } } else if (plug == mOutSubDArrayAttr) { if (mOutRead[2]) { // Reference the output to let EM know we are the writer // of the data. EM sets the output to holder and causes // race condition when evaluating fan-out destinations. MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutSubDArrayAttr, &status); const unsigned int elementCount = outArrayHandle.elementCount(); for (unsigned int j = 0; j < elementCount; j++) { outArrayHandle.outputValue().data(); outArrayHandle.next(); } outArrayHandle.setAllClean(); return MS::kSuccess; } mOutRead[2] = true; unsigned int subDSize = static_cast<unsigned int>(mData.mSubDList.size()); if (subDSize > 0) { MArrayDataHandle outArrayHandle = dataBlock.outputValue( mOutSubDArrayAttr, &status); MDataHandle outHandle; for (unsigned int j = 0; j < subDSize; j++) { // these elements can be sparse if they have been deleted if (outArrayHandle.elementIndex() != j) { continue; } outHandle = outArrayHandle.outputValue(&status); outArrayHandle.next(); MObject obj = outHandle.data(); if (obj.hasFn(MFn::kMesh)) { MFnMesh fnMesh(obj); readSubD(mCurTime, fnMesh, obj, mData.mSubDList[j], mSubDInitialized); outHandle.set(obj); } } mSubDInitialized = true; outArrayHandle.setAllClean(); } // for the case where we don't have any nodes, we want to make sure // to push out empty meshes on our connections, this can happen if // the input file was offlined, currently we only need to do this for // meshes as Nurbs, curves, and the other channels don't crash Maya else { MArrayDataHandle outArrayHandle = dataBlock.outputValue( mOutSubDArrayAttr, &status); if (outArrayHandle.elementCount() > 0) { do { MDataHandle outHandle = outArrayHandle.outputValue(); MObject obj = outHandle.data(); if (obj.hasFn(MFn::kMesh)) { MFloatPointArray emptyVerts; MIntArray emptyCounts; MIntArray emptyConnects; MFnMesh emptyMesh; emptyMesh.create(0, 0, emptyVerts, emptyCounts, emptyConnects, obj); outHandle.set(obj); } } while (outArrayHandle.next() == MS::kSuccess); } mSubDInitialized = true; outArrayHandle.setAllClean(); } } else if (plug == mOutPolyArrayAttr) { if (mOutRead[3]) { // Reference the output to let EM know we are the writer // of the data. EM sets the output to holder and causes // race condition when evaluating fan-out destinations. MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutPolyArrayAttr, &status); const unsigned int elementCount = outArrayHandle.elementCount(); for (unsigned int j = 0; j < elementCount; j++) { outArrayHandle.outputValue().data(); outArrayHandle.next(); } outArrayHandle.setAllClean(); return MS::kSuccess; } mOutRead[3] = true; unsigned int polySize = static_cast<unsigned int>(mData.mPolyMeshList.size()); if (polySize > 0) { MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutPolyArrayAttr, &status); MDataHandle outHandle; for (unsigned int j = 0; j < polySize; j++) { // these elements can be sparse if they have been deleted if (outArrayHandle.elementIndex() != j) { continue; } outHandle = outArrayHandle.outputValue(&status); outArrayHandle.next(); MObject obj = outHandle.data(); if (obj.hasFn(MFn::kMesh)) { MFnMesh fnMesh(obj); readPoly(mCurTime, fnMesh, obj, mData.mPolyMeshList[j], mPolyInitialized); outHandle.set(obj); } } mPolyInitialized = true; outArrayHandle.setAllClean(); } // for the case where we don't have any nodes, we want to make sure // to push out empty meshes on our connections, this can happen if // the input file was offlined, currently we only need to do this for // meshes as Nurbs, curves, and the other channels don't crash Maya else { MArrayDataHandle outArrayHandle = dataBlock.outputValue( mOutPolyArrayAttr, &status); if (outArrayHandle.elementCount() > 0) { do { MDataHandle outHandle = outArrayHandle.outputValue(&status); MObject obj = outHandle.data(); if (obj.hasFn(MFn::kMesh)) { MFloatPointArray emptyVerts; MIntArray emptyCounts; MIntArray emptyConnects; MFnMesh emptyMesh; emptyMesh.create(0, 0, emptyVerts, emptyCounts, emptyConnects, obj); outHandle.set(obj); } } while (outArrayHandle.next() == MS::kSuccess); } mPolyInitialized = true; outArrayHandle.setAllClean(); } } else if (plug == mOutCameraArrayAttr) { if (mOutRead[4]) { dataBlock.setClean(plug); return MS::kSuccess; } mOutRead[4] = true; unsigned int cameraSize = static_cast<unsigned int>(mData.mCameraList.size()); if (cameraSize > 0) { MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutCameraArrayAttr, &status); MPlug arrayPlug(thisMObject(), mOutCameraArrayAttr); double angleConversion = 1.0; switch (MAngle::uiUnit()) { case MAngle::kRadians: angleConversion = 0.017453292519943295; break; case MAngle::kAngMinutes: angleConversion = 60.0; break; case MAngle::kAngSeconds: angleConversion = 3600.0; break; default: break; } MDataHandle outHandle; unsigned int index = 0; for (unsigned int cameraIndex = 0; cameraIndex < cameraSize; cameraIndex++) { Alembic::AbcGeom::ICamera & cam = mData.mCameraList[cameraIndex]; std::vector<double> array; read(mCurTime, cam, array); for (unsigned int dataIndex = 0; dataIndex < array.size(); dataIndex++, index++) { // skip over sparse elements if (index != outArrayHandle.elementIndex()) { continue; } outHandle = outArrayHandle.outputValue(&status); outArrayHandle.next(); // not shutter angle index, so not an angle if (dataIndex != 11) { outHandle.set(array[dataIndex]); } else { outHandle.set(array[dataIndex] * angleConversion); } } // for the per camera data handles } // for each camera outArrayHandle.setAllClean(); } } else if (plug == mOutNurbsSurfaceArrayAttr) { if (mOutRead[5]) { // Reference the output to let EM know we are the writer // of the data. EM sets the output to holder and causes // race condition when evaluating fan-out destinations. MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutNurbsSurfaceArrayAttr, &status); const unsigned int elementCount = outArrayHandle.elementCount(); for (unsigned int j = 0; j < elementCount; j++) { outArrayHandle.outputValue().data(); outArrayHandle.next(); } outArrayHandle.setAllClean(); return MS::kSuccess; } mOutRead[5] = true; unsigned int nSurfaceSize = static_cast<unsigned int>(mData.mNurbsList.size()); if (nSurfaceSize > 0) { MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutNurbsSurfaceArrayAttr, &status); MDataHandle outHandle; for (unsigned int j = 0; j < nSurfaceSize; j++) { // these elements can be sparse if they have been deleted if (outArrayHandle.elementIndex() != j) continue; outHandle = outArrayHandle.outputValue(&status); outArrayHandle.next(); MObject obj = outHandle.data(); if (obj.hasFn(MFn::kNurbsSurface)) { readNurbs(mCurTime, mData.mNurbsList[j], obj); outHandle.set(obj); } } outArrayHandle.setAllClean(); } } else if (plug == mOutNurbsCurveGrpArrayAttr) { if (mOutRead[6]) { // Reference the output to let EM know we are the writer // of the data. EM sets the output to holder and causes // race condition when evaluating fan-out destinations. MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutNurbsCurveGrpArrayAttr, &status); const unsigned int elementCount = outArrayHandle.elementCount(); for (unsigned int j = 0; j < elementCount; j++) { outArrayHandle.outputValue().data(); outArrayHandle.next(); } outArrayHandle.setAllClean(); return MS::kSuccess; } mOutRead[6] = true; unsigned int nCurveGrpSize = static_cast<unsigned int>(mData.mCurvesList.size()); if (nCurveGrpSize > 0) { MArrayDataHandle outArrayHandle = dataBlock.outputValue(mOutNurbsCurveGrpArrayAttr, &status); MDataHandle outHandle; std::vector<MObject> curvesObj; for (unsigned int i = 0; i < nCurveGrpSize; ++i) { readCurves(mCurTime, mData.mCurvesList[i], mData.mNumCurves[i], curvesObj); } std::size_t numChild = curvesObj.size(); // not the best way to do this // only reading bunches of curves based on the connections would be // more efficient when there is a bunch of broken connections for (unsigned int i = 0; i < numChild; i++) { if (outArrayHandle.elementIndex() != i) { continue; } outHandle = outArrayHandle.outputValue(&status); outArrayHandle.next(); status = outHandle.set(curvesObj[i]); } outArrayHandle.setAllClean(); } } else { return MS::kUnknownParameter; } dataBlock.setClean(plug); return status; }
MStatus mapBlendShape::deform(MDataBlock& data, MItGeometry& itGeo, const MMatrix& localToWorldMatrix, unsigned int geomIndex) { MStatus status; // get the blendMesh MDataHandle hBlendMesh = data.inputValue( aBlendMesh, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); MObject oBlendMesh = hBlendMesh.asMesh(); if (oBlendMesh.isNull()) { return MS::kSuccess; } MFnMesh fnMesh( oBlendMesh, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); MPointArray blendPoints; fnMesh.getPoints( blendPoints ); // get the dirty flags for the input and blendMap bool inputGeomClean = data.isClean(inputGeom, &status); bool blendMapClean = data.isClean(aBlendMap, &status); if (!blendMapClean) { lumValues.reserve(itGeo.count()); } MDoubleArray uCoords, vCoords; MVectorArray resultColors; MDoubleArray resultAlphas; uCoords.setLength(1); vCoords.setLength(1); bool hasTextureNode; bool useBlendMap = data.inputValue(aUseBlendMap).asBool(); float blendMapMultiplier = data.inputValue(aBlendMapMultiplier).asFloat(); if (blendMapMultiplier<=0.0) { useBlendMap = false; } if (useBlendMap) { hasTextureNode = MDynamicsUtil::hasValidDynamics2dTexture(thisMObject(), aBlendMap); } float env = data.inputValue(envelope).asFloat(); MPoint point; float2 uvPoint; float w, lum; for ( ; !itGeo.isDone(); itGeo.next() ) { lum = 1.0; if (useBlendMap) { if (!blendMapClean) { fnMesh.getUVAtPoint(blendPoints[itGeo.index()], uvPoint); if (hasTextureNode) { uCoords[0] = uvPoint[0]; vCoords[0] = uvPoint[1]; MDynamicsUtil::evalDynamics2dTexture(thisMObject(), aBlendMap, uCoords, vCoords, &resultColors, &resultAlphas); lum = float(resultColors[0][0]); } lumValues[itGeo.index()] = lum; } else { lum = lumValues[itGeo.index()]; } } point = itGeo.position(); w = weightValue( data, geomIndex, itGeo.index() ); point += (blendPoints[itGeo.index()] - point) * env * w * lum * blendMapMultiplier; itGeo.setPosition( point ); } return MS::kSuccess; }
/* virtual */ MStatus hwColorPerVertexShader::glGeometry( const MDagPath& path, int prim, unsigned int writable, int indexCount, const unsigned int * indexArray, int vertexCount, const int * vertexIDs, const float * vertexArray, int normalCount, const float ** normalArrays, int colorCount, const float ** colorArrays, int texCoordCount, const float ** texCoordArrays) { // If this attribute is enabled, normals, tangents, // and binormals can be visualized using false coloring. // Negative values will clamp to black however. #ifdef _TEST_FILE_PATH_DURING_DRAW_ if (path.hasFn( MFn::kMesh ) ) { // Check the # of uvsets. If no uvsets // then can't return tangent or binormals // MGlobal::displayInfo( path.fullPathName() ); MFnMesh fnMesh( path.node() ); numUVSets = fnMesh.numUVSets(); } #endif if ((unsigned int)normalCount > mNormalsPerVertex) normalCount = mNormalsPerVertex; if (normalCount > 0) { glPushAttrib(GL_ALL_ATTRIB_BITS); glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); glDisable(GL_LIGHTING); glDisable(GL_BLEND); if (normalCount > 1) { if (normalCount == 2) { //#define _TANGENT_DEBUG #ifdef _TANGENT_DEBUG const float *tangents = (const float *)&normalArrays[1][0]; for (int i=0; i< vertexCount; i++) { cout<<"tangent["<<i<<"] = "<<tangents[i*3] <<","<<tangents[i*3+1]<<","<<tangents[i*3+2]<<endl; } #endif glEnableClientState(GL_COLOR_ARRAY); glColorPointer(3, GL_FLOAT, 0, &normalArrays[1][0]); } else { #ifdef _BINORMAL_DEBUG const float *binormals = (const float *)&normalArrays[2][0]; for (unsigned int i=0; i< vertexCount; i++) { cout<<"binormals["<<i<<"] = "<<binormals[i*3] <<","<<binormals[i*3+1]<<","<<binormals[i*3+2]<<endl; } #endif glEnableClientState(GL_COLOR_ARRAY); glColorPointer(3, GL_FLOAT, 0, &normalArrays[2][0]); } } else if (normalCount) { glEnableClientState(GL_COLOR_ARRAY); glColorPointer(3, GL_FLOAT, 0, &normalArrays[0][0]); } glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer ( 3, GL_FLOAT, 0, &vertexArray[0] ); glDrawElements ( prim, indexCount, GL_UNSIGNED_INT, indexArray ); glDisableClientState(GL_COLOR_ARRAY); glPopClientAttrib(); glPopAttrib(); return MS::kSuccess; } else { return draw( prim, writable, indexCount, indexArray, vertexCount, vertexArray, colorCount, colorArrays ); } }
MStatus findTexturesPerPolygon::doIt( const MArgList& ) // // Description: // Find the texture files that apply to the color of each polygon of // a selected shape if the shape has its polygons organized into sets. // { // Get the selection and choose the first path on the selection list. // MStatus status; MDagPath path; MObject cmp; MSelectionList slist; MGlobal::getActiveSelectionList(slist); slist.getDagPath(0, path, cmp); // Have to make the path include the shape below it so that // we can determine if the underlying shape node is instanced. // By default, dag paths only include transform nodes. // path.extendToShape(); // If the shape is instanced then we need to determine which // instance this path refers to. // int instanceNum = 0; if (path.isInstanced()) instanceNum = path.instanceNumber(); // Get a list of all sets pertaining to the selected shape and the // members of those sets. // MFnMesh fnMesh(path); MObjectArray sets; MObjectArray comps; if (!fnMesh.getConnectedSetsAndMembers(instanceNum, sets, comps, true)) cerr << "ERROR: MFnMesh::getConnectedSetsAndMembers\n"; // Loop through all the sets. If the set is a polygonal set, find the // shader attached to the and print out the texture file name for the // set along with the polygons in the set. // for ( unsigned i=0; i<sets.length(); i++ ) { MObject set = sets[i]; MObject comp = comps[i]; MFnSet fnSet( set, &status ); if (status == MS::kFailure) { cerr << "ERROR: MFnSet::MFnSet\n"; continue; } // Make sure the set is a polygonal set. If not, continue. MItMeshPolygon piter(path, comp, &status); if ((status == MS::kFailure) || comp.isNull()) continue; // Find the texture that is applied to this set. First, get the // shading node connected to the set. Then, if there is an input // attribute called "color", search upstream from it for a texture // file node. // MObject shaderNode = findShader(set); if (shaderNode == MObject::kNullObj) continue; MPlug colorPlug = MFnDependencyNode(shaderNode).findPlug("color", &status); if (status == MS::kFailure) continue; MItDependencyGraph dgIt(colorPlug, MFn::kFileTexture, MItDependencyGraph::kUpstream, MItDependencyGraph::kBreadthFirst, MItDependencyGraph::kNodeLevel, &status); if (status == MS::kFailure) continue; dgIt.disablePruningOnFilter(); // If no texture file node was found, just continue. // if (dgIt.isDone()) continue; // Print out the texture node name and texture file that it references. // MObject textureNode = dgIt.thisNode(); MPlug filenamePlug = MFnDependencyNode(textureNode).findPlug("fileTextureName"); MString textureName; filenamePlug.getValue(textureName); cerr << "Set: " << fnSet.name() << endl; cerr << "Texture Node Name: " << MFnDependencyNode(textureNode).name() << endl; cerr << "Texture File Name: " << textureName.asChar() << endl; // Print out the set of polygons that are contained in the current set. // for ( ; !piter.isDone(); piter.next() ) cerr << " poly component: " << piter.index() << endl; } return MS::kSuccess; }
collision_shape_t::pointer collisionShapeNode::createCollisionShape(const MObject& node) { collision_shape_t::pointer collision_shape = 0; MObject thisObject(thisMObject()); MPlug plgType(thisObject, ia_type); int type; plgType.getValue(type); switch(type) { case 0: { //convex hull { if(node.hasFn(MFn::kMesh)) { MDagPath dagPath; MDagPath::getAPathTo(node, dagPath); MFnMesh fnMesh(dagPath); MFloatPointArray mpoints; MFloatVectorArray mnormals; MIntArray mtrianglecounts; MIntArray mtrianglevertices; fnMesh.getPoints(mpoints, MSpace::kObject); fnMesh.getNormals(mnormals, MSpace::kObject); fnMesh.getTriangles(mtrianglecounts, mtrianglevertices); std::vector<vec3f> vertices(mpoints.length()); std::vector<vec3f> normals(mpoints.length()); std::vector<unsigned int> indices(mtrianglevertices.length()); btAlignedObjectArray<btVector3> btVerts; //mb for(size_t i = 0; i < vertices.size(); ++i) { vertices[i] = vec3f(mpoints[i].x, mpoints[i].y, mpoints[i].z); normals[i] = vec3f(mnormals[i].x, mnormals[i].y, mnormals[i].z); #if UPDATE_SHAPE //future collision margin adjust btVerts.push_back(btVector3(mpoints[i].x, mpoints[i].y, mpoints[i].z)); //mb #endif } for(size_t i = 0; i < indices.size(); ++i) { indices[i] = mtrianglevertices[i]; } #if UPDATE_SHAPE //future collision margin adjust btAlignedObjectArray<btVector3> planeEquations; btGeometryUtil::getPlaneEquationsFromVertices(btVerts, planeEquations); btAlignedObjectArray<btVector3> shiftedPlaneEquations; for (int p=0;p<planeEquations.size();p++) { btVector3 plane = planeEquations[p]; plane[3] += collisionShapeNode::collisionMarginOffset; shiftedPlaneEquations.push_back(plane); } btAlignedObjectArray<btVector3> shiftedVertices; btGeometryUtil::getVerticesFromPlaneEquations(shiftedPlaneEquations, shiftedVertices); std::vector<vec3f> shiftedVerticesVec3f(shiftedVertices.size()); for(size_t i = 0; i < shiftedVertices.size(); ++i) { shiftedVerticesVec3f[i] = vec3f(shiftedVertices[i].getX(), shiftedVertices[i].getY(), shiftedVertices[i].getZ()); //std::cout << "orig verts: " << vertices[i][0] << " " << vertices[i][1] << " " << vertices[i][2] << std::endl; //std::cout << "shft verts: " << shiftedVertices[i].getX() << " " << shiftedVertices[i].getY() << " " << shiftedVertices[i].getZ() << std::endl; //std::cout << std::endl; } collision_shape = solver_t::create_convex_hull_shape(&(shiftedVerticesVec3f[0]), shiftedVerticesVec3f.size(), &(normals[0]), &(indices[0]), indices.size()); #endif #if UPDATE_SHAPE == 0 collision_shape = solver_t::create_convex_hull_shape(&(vertices[0]), vertices.size(), &(normals[0]), &(indices[0]), indices.size()); //original #endif } } } break; case 1: { //mesh { if(node.hasFn(MFn::kMesh)) { MDagPath dagPath; MDagPath::getAPathTo(node, dagPath); MFnMesh fnMesh(dagPath); MFloatPointArray mpoints; MFloatVectorArray mnormals; MIntArray mtrianglecounts; MIntArray mtrianglevertices; fnMesh.getPoints(mpoints, MSpace::kObject); fnMesh.getNormals(mnormals, MSpace::kObject); fnMesh.getTriangles(mtrianglecounts, mtrianglevertices); std::vector<vec3f> vertices(mpoints.length()); std::vector<vec3f> normals(mpoints.length()); std::vector<unsigned int> indices(mtrianglevertices.length()); for(size_t i = 0; i < vertices.size(); ++i) { vertices[i] = vec3f(mpoints[i].x, mpoints[i].y, mpoints[i].z); normals[i] = vec3f(mnormals[i].x, mnormals[i].y, mnormals[i].z); } for(size_t i = 0; i < indices.size(); ++i) { indices[i] = mtrianglevertices[i]; } bool dynamicMesh = true; collision_shape = solver_t::create_mesh_shape(&(vertices[0]), vertices.size(), &(normals[0]), &(indices[0]), indices.size(),dynamicMesh); } } } break; case 2: //cylinder break; case 3: //capsule break; case 7: //btBvhTriangleMeshShape { if(node.hasFn(MFn::kMesh)) { MDagPath dagPath; MDagPath::getAPathTo(node, dagPath); MFnMesh fnMesh(dagPath); MFloatPointArray mpoints; MFloatVectorArray mnormals; MIntArray mtrianglecounts; MIntArray mtrianglevertices; fnMesh.getPoints(mpoints, MSpace::kObject); fnMesh.getNormals(mnormals, MSpace::kObject); fnMesh.getTriangles(mtrianglecounts, mtrianglevertices); std::vector<vec3f> vertices(mpoints.length()); std::vector<vec3f> normals(mpoints.length()); std::vector<unsigned int> indices(mtrianglevertices.length()); for(size_t i = 0; i < vertices.size(); ++i) { vertices[i] = vec3f(mpoints[i].x, mpoints[i].y, mpoints[i].z); normals[i] = vec3f(mnormals[i].x, mnormals[i].y, mnormals[i].z); } for(size_t i = 0; i < indices.size(); ++i) { indices[i] = mtrianglevertices[i]; } bool dynamicMesh = false; collision_shape = solver_t::create_mesh_shape(&(vertices[0]), vertices.size(), &(normals[0]), &(indices[0]), indices.size(),dynamicMesh); } } break; case 8: //hacd convex decomposition { { if(node.hasFn(MFn::kMesh)) { MDagPath dagPath; MDagPath::getAPathTo(node, dagPath); MFnMesh fnMesh(dagPath); MFloatPointArray mpoints; MFloatVectorArray mnormals; MIntArray mtrianglecounts; MIntArray mtrianglevertices; fnMesh.getPoints(mpoints, MSpace::kObject); fnMesh.getNormals(mnormals, MSpace::kObject); fnMesh.getTriangles(mtrianglecounts, mtrianglevertices); std::vector<vec3f> vertices(mpoints.length()); std::vector<vec3f> normals(mpoints.length()); std::vector<unsigned int> indices(mtrianglevertices.length()); for(size_t i = 0; i < vertices.size(); ++i) { vertices[i] = vec3f(mpoints[i].x, mpoints[i].y, mpoints[i].z); normals[i] = vec3f(mnormals[i].x, mnormals[i].y, mnormals[i].z); } for(size_t i = 0; i < indices.size(); ++i) { indices[i] = mtrianglevertices[i]; } bool dynamicMesh = false; collision_shape = solver_t::create_hacd_shape(&(vertices[0]), vertices.size(), &(normals[0]), &(indices[0]), indices.size(),dynamicMesh); } } } break; default: { } } return collision_shape; }
MStatus PushDeformer::deform(MDataBlock& dataBlock, MItGeometry& itGeo, const MMatrix& localToWorldMatrix, unsigned int geomIndex) { MStatus status; //get attribute handles double bulgeAmount = dataBlock.inputValue(aAmount, &status).asDouble(); CHECK_MSTATUS_AND_RETURN_IT(status); m_taskData.envelope = dataBlock.inputValue(envelope, &status).asFloat(); CHECK_MSTATUS_AND_RETURN_IT(status); bool useStressV = dataBlock.inputValue(aUseStress, &status).asBool(); CHECK_MSTATUS_AND_RETURN_IT(status); int multiThreadingType = dataBlock.inputValue(aMultiThreadingType, &status).asBool(); CHECK_MSTATUS_AND_RETURN_IT(status); if (m_taskData.envelope <= 0.001) { return MS::kSuccess; } // if the use stress plug is turned on pull MDoubleArray stressV; if (useStressV == true) { //pull out the raw data as an Mobject MObject stressMap = dataBlock.inputValue(aStressMap, &status).data(); CHECK_MSTATUS_AND_RETURN_IT(status); MFnDoubleArrayData stressDataFn(stressMap); m_taskData.stressV = stressDataFn.array(); } //retrieve the handle to the output array attribute MArrayDataHandle hInput = dataBlock.outputArrayValue(input, &status); CHECK_MSTATUS_AND_RETURN_IT(status); //get the input array index handle status = hInput.jumpToElement(geomIndex); //get the handle of geomIndex attribute MDataHandle hInputElement = hInput.outputValue(&status); CHECK_MSTATUS_AND_RETURN_IT(status); //Get the MObject of the input geometry of geomindex MObject oInputGeom = hInputElement.child(inputGeom).asMesh(); MFnMesh fnMesh(oInputGeom, &status); CHECK_MSTATUS_AND_RETURN_IT(status); fnMesh.getVertexNormals(false, m_taskData.normals, MSpace::kWorld); itGeo.allPositions(m_taskData.points, MSpace::kWorld); //MGlobal::displayInfo( "test" ); /*for (int i = 0; i < itGeo.count(); i++) { MGlobal::displayInfo( MFnAttribute(weightList).isArray ); }*/ m_taskData.bulgeAmount = bulgeAmount; if(multiThreadingType == 1) { ThreadData* pThreadData = createThreadData( NUM_TASKS, &m_taskData ); MThreadPool::newParallelRegion( createTasks, (void*)pThreadData ); itGeo.setAllPositions(m_taskData.points); delete [] pThreadData; return MS::kSuccess; } else if(multiThreadingType == 2) { tbb::parallel_for(size_t(0), size_t(itGeo.count()), [this](size_t i) { //const float w = weightValue(dataBlock, geomIndex, i); const float w = 1.0; if (m_taskData.useStressV == true && (m_taskData.stressV.length() > 0)) { //deform m_taskData.points[i] += (MVector(m_taskData.normals[i]) * m_taskData.bulgeAmount * m_taskData.envelope * w * m_taskData.stressV[i]); } else { //deform m_taskData.points[i] += m_taskData.normals[i] * m_taskData.bulgeAmount * m_taskData.envelope * w; } }); } // else if(multiThreadingType == 3) #pragma omp parallel for for (int i = 0; i < itGeo.count(); i++) { float w = weightValue(dataBlock, geomIndex, itGeo.index()); if (useStressV == true && (stressV.length() > 0)) { //deform m_taskData.points[i] += (MVector(m_taskData.normals[i]) * bulgeAmount * m_taskData.envelope * w * m_taskData.stressV[i]); } else { //deform m_taskData.points[i] += m_taskData.normals[i] * bulgeAmount * m_taskData.envelope * w; } } else { for (; !itGeo.isDone(); itGeo.next()) { float w = weightValue(dataBlock, geomIndex, itGeo.index()); if (useStressV == true && (stressV.length() > 0)) { //deform m_taskData.points[itGeo.index()] += (MVector(m_taskData.normals[itGeo.index()]) * bulgeAmount * m_taskData.envelope * w * m_taskData.stressV[itGeo.index()]); } else { //deform m_taskData.points[itGeo.index()] += m_taskData.normals[itGeo.index()] * bulgeAmount * m_taskData.envelope * w; } } } itGeo.setAllPositions(m_taskData.points); return MS::kSuccess; }
MObject createPoly(double iFrame, PolyMeshAndColors & iNode, MObject & iParent) { Alembic::AbcGeom::IPolyMeshSchema schema = iNode.mMesh.getSchema(); MString name(iNode.mMesh.getName().c_str()); MObject obj; // add other properties if (!schema.isConstant()) { MFloatPointArray emptyPt; MIntArray emptyInt; MFnMesh fnMesh; obj = fnMesh.create(0, 0, emptyPt, emptyInt, emptyInt, iParent); fnMesh.setName(name); } else { Alembic::AbcCoreAbstract::index_t index, ceilIndex; double alpha = getWeightAndIndex(iFrame, schema.getTimeSampling(), schema.getNumSamples(), index, ceilIndex); Alembic::AbcGeom::IPolyMeshSchema::Sample samp; schema.get(samp, Alembic::Abc::ISampleSelector(index)); MFloatPointArray ptArray; Alembic::Abc::P3fArraySamplePtr ceilPoints; if (index != ceilIndex) { Alembic::AbcGeom::IPolyMeshSchema::Sample ceilSamp; schema.get(ceilSamp, Alembic::Abc::ISampleSelector(ceilIndex)); ceilPoints = ceilSamp.getPositions(); } fillPoints(ptArray, samp.getPositions(), ceilPoints, alpha); MFnMesh fnMesh; fillTopology(fnMesh, iParent, ptArray, samp.getFaceIndices(), samp.getFaceCounts()); fnMesh.setName(iNode.mMesh.getName().c_str()); setPolyNormals(iFrame, fnMesh, schema.getNormalsParam()); setUVs(iFrame, fnMesh, schema.getUVsParam()); obj = fnMesh.object(); } MFnMesh fnMesh(obj); MString pathName = fnMesh.partialPathName(); setInitialShadingGroup(pathName); setColors(iFrame, fnMesh, iNode.mC3s, iNode.mC4s, true); if ( !schema.getNormalsParam().valid() ) { MFnNumericAttribute attr; MString attrName("noNormals"); MObject attrObj = attr.create(attrName, attrName, MFnNumericData::kBoolean, true); attr.setKeyable(true); attr.setHidden(false); fnMesh.addAttribute(attrObj, MFnDependencyNode::kLocalDynamicAttr); } return obj; }
void liqRibData::addAdditionalSurfaceParameters( MObject node ) { LIQDEBUGPRINTF("-> scanning for additional rman surface attributes \n"); MStatus status = MS::kSuccess; unsigned i; // work out how many elements there would be in a facevarying array if a mesh or subD // faceVaryingCount is a private data member if ( ( type() == MRT_Mesh ) || ( type() == MRT_Subdivision ) ) { faceVaryingCount = 0; MFnMesh fnMesh( node ); for ( uint pOn = 0; pOn < fnMesh.numPolygons(); pOn++ ) { faceVaryingCount += fnMesh.polygonVertexCount( pOn ); } } // find how many additional MFnDependencyNode nodeFn( node ); // find the attributes MStringArray floatAttributesFound = findAttributesByPrefix( "rmanF", nodeFn ); MStringArray pointAttributesFound = findAttributesByPrefix( "rmanP", nodeFn ); MStringArray vectorAttributesFound = findAttributesByPrefix( "rmanV", nodeFn ); MStringArray normalAttributesFound = findAttributesByPrefix( "rmanN", nodeFn ); MStringArray colorAttributesFound = findAttributesByPrefix( "rmanC", nodeFn ); MStringArray stringAttributesFound = findAttributesByPrefix( "rmanS", nodeFn ); if ( floatAttributesFound.length() > 0 ) { for ( i = 0; i < floatAttributesFound.length(); i++ ) { liqTokenPointer tokenPointerPair; MString cutString = floatAttributesFound[i].substring(5, floatAttributesFound[i].length()); MPlug fPlug = nodeFn.findPlug( floatAttributesFound[i] ); MObject plugObj; status = fPlug.getValue( plugObj ); if ( plugObj.apiType() == MFn::kDoubleArrayData ) { MFnDoubleArrayData fnDoubleArrayData( plugObj ); MDoubleArray doubleArrayData = fnDoubleArrayData.array( &status ); tokenPointerPair.set( cutString.asChar(), rFloat, ( type() == MRT_Nurbs || type() == MRT_NuCurve ) ? true : false, true, false, doubleArrayData.length() ); for( unsigned int kk = 0; kk < doubleArrayData.length(); kk++ ) { tokenPointerPair.setTokenFloat( kk, doubleArrayData[kk] ); } if ( ( type() == MRT_NuCurve ) && ( cutString == MString( "width" ) ) ) { tokenPointerPair.setDetailType( rVarying); } else if ( ( ( type() == MRT_Mesh ) || ( type() == MRT_Subdivision ) ) && ( doubleArrayData.length() == faceVaryingCount ) ) { tokenPointerPair.setDetailType( rFaceVarying); } else { tokenPointerPair.setDetailType( rVertex ); } } else { if( fPlug.isArray() ) { int nbElts = fPlug.evaluateNumElements(); float floatValue; tokenPointerPair.set( cutString.asChar(), rFloat, ( type() == MRT_Nurbs || type() == MRT_NuCurve ) ? true : false, false, true, // philippe :passed as uArray, otherwise it will think it is a single float nbElts ); MPlug elementPlug; for( unsigned int kk = 0; kk < nbElts; kk++ ) { elementPlug = fPlug.elementByPhysicalIndex(kk); elementPlug.getValue( floatValue ); tokenPointerPair.setTokenFloat( kk, floatValue ); } tokenPointerPair.setDetailType( rConstant ); } else { float floatValue; tokenPointerPair.set( cutString.asChar(), rFloat, ( type() == MRT_Nurbs || type() == MRT_NuCurve ) ? true : false, false, false, 0 ); fPlug.getValue( floatValue ); tokenPointerPair.setTokenFloat( 0, floatValue ); tokenPointerPair.setDetailType( rConstant ); } } tokenPointerArray.push_back( tokenPointerPair ); } } if ( pointAttributesFound.length() > 0 ) { for ( i = 0; i < pointAttributesFound.length(); i++ ) { liqTokenPointer tokenPointerPair; MString cutString = pointAttributesFound[i].substring(5, pointAttributesFound[i].length()); MPlug pPlug = nodeFn.findPlug( pointAttributesFound[i] ); MObject plugObj; status = pPlug.getValue( plugObj ); if ( plugObj.apiType() == MFn::kPointArrayData ) { MFnPointArrayData fnPointArrayData( plugObj ); MPointArray pointArrayData = fnPointArrayData.array( &status ); tokenPointerPair.set( cutString.asChar(), rPoint, ( type() == MRT_Nurbs || type() == MRT_NuCurve ) ? true : false, true, false, pointArrayData.length() ); if ( type() == MRT_Nurbs || type() == MRT_NuCurve ) { for ( int kk = 0; kk < pointArrayData.length(); kk++ ) { tokenPointerPair.setTokenFloat( kk, pointArrayData[kk].x, pointArrayData[kk].y, pointArrayData[kk].z, pointArrayData[kk].w ); } } else { for ( int kk = 0; kk < pointArrayData.length(); kk++ ) { tokenPointerPair.setTokenFloat( kk, pointArrayData[kk].x, pointArrayData[kk].y, pointArrayData[kk].z ); } } tokenPointerPair.setDetailType( rVertex ); } else { // Hmmmm float ? double ? float x, y, z; tokenPointerPair.set( cutString.asChar(), rPoint, ( type() == MRT_Nurbs || type() == MRT_NuCurve ) ? true : false, false, false, 0 ); // Hmmm should check as for arrays if we are in nurbs mode : 4 values pPlug.child(0).getValue( x ); pPlug.child(1).getValue( y ); pPlug.child(2).getValue( z ); tokenPointerPair.setTokenFloat( 0, x, y, z ); tokenPointerPair.setDetailType( rConstant ); } tokenPointerArray.push_back( tokenPointerPair ); } } parseVectorAttributes( nodeFn, vectorAttributesFound, rVector ); parseVectorAttributes( nodeFn, normalAttributesFound, rNormal ); parseVectorAttributes( nodeFn, colorAttributesFound, rColor ); if ( stringAttributesFound.length() > 0 ) { for ( i = 0; i < stringAttributesFound.length(); i++ ) { liqTokenPointer tokenPointerPair; MString cutString = stringAttributesFound[i].substring(5, stringAttributesFound[i].length()); MPlug sPlug = nodeFn.findPlug( stringAttributesFound[i] ); MObject plugObj; status = sPlug.getValue( plugObj ); tokenPointerPair.set( cutString.asChar(), rString, ( type() == MRT_Nurbs || type() == MRT_NuCurve ) ? true : false, false, false, 0 ); MString stringVal; sPlug.getValue( stringVal ); tokenPointerPair.setTokenString( 0, stringVal.asChar(), stringVal.length() ); tokenPointerPair.setDetailType( rConstant ); tokenPointerArray.push_back( tokenPointerPair ); } } }