MStatus HelixBases_sort(MObjectArray & input, MObjectArray & result) { MStatus status; result.setSizeIncrement(input.length()); while(input.length() > 0) { double z = std::numeric_limits<double>::max(); unsigned int z_index = 0; for(unsigned int i = 0; i < input.length(); ++i) { MFnTransform transform(input[i]); MVector translation = transform.getTranslation(MSpace::kTransform, &status); if (!status) { status.perror("MFnTransform::getTranslation"); return status; } if (translation.z < z) { z = translation.z; z_index = i; } } result.append(input[z_index]); input.remove(z_index); } return MStatus::kSuccess; }
bool skinClusterWeights::isSkinClusterIncluded(MObject &node) { MStatus status; unsigned int i; if (skinClusterArray.length() == 0) return true; for (i = 0; i < skinClusterArray.length(); i++) { if (skinClusterArray[i] == node) return true; } return false; }
AlembicWriteJob::AlembicWriteJob(const MString &in_FileName, const MObjectArray &in_Selection, const MDoubleArray &in_Frames, bool use_ogawa, const std::vector<std::string> &in_prefixFilters, const std::set<std::string> &in_attributes, const std::vector<std::string> &in_userPrefixFilters, const std::set<std::string> &in_userAttributes) : useOgawa(use_ogawa), mPrefixFilters(in_prefixFilters), mAttributes(in_attributes), mUserPrefixFilters(in_userPrefixFilters), mUserAttributes(in_userAttributes) { // ensure to clear the isRefAnimated cache clearIsRefAnimatedCache(); mFileName = in_FileName; for (unsigned int i = 0; i < in_Selection.length(); i++) { mSelection.append(in_Selection[i]); } for (unsigned int i = 0; i < in_Frames.length(); i++) { mFrames.push_back(in_Frames[i]); } }
void EntityNode::UnloadArt() { MStatus stat; // remove anything currently imported/referenced MFnDagNode dagFn( thisMObject() ); while( dagFn.childCount() ) { stat = MGlobal::deleteNode( dagFn.child( 0 ) ); MContinueErr( stat, ("Unable to delete" + dagFn.fullPathName() ).asChar() ); } ClearInstances(); MObjectArray forDelete; GetImportNodes( forDelete ); MFnDependencyNode depFn; u32 num = forDelete.length(); for( u32 i = 0; i < num; ++i ) { MObject& node = forDelete[i]; MObjectHandle handle( node ); if( !handle.isValid() ) continue; depFn.setObject( node ); stat = MGlobal::deleteNode( node ); MContinueErr( stat, ("Unable to delete" + depFn.name() ).asChar() ); } forDelete.clear(); }
TheaSDK::Normal3D TheaRenderer::getSunDirection() { MFnDependencyNode depFn(getRenderGlobalsNode()); std::shared_ptr<RenderGlobals> renderGlobals = MayaTo::getWorldPtr()->worldRenderGlobalsPtr; std::shared_ptr<TheaRenderer> renderer = std::static_pointer_cast<TheaRenderer>(MayaTo::getWorldPtr()->worldRendererPtr); TheaSDK::Normal3D sunDir; MObjectArray nodeList; getConnectedInNodes(MString("sunLightConnection"), getRenderGlobalsNode(), nodeList); if( nodeList.length() > 0) { MVector lightDir(0,0,1); MFnDagNode sunDagNode(nodeList[0]); //lightDir *= this->mtth_renderGlobals->globalConversionMatrix.inverse(); lightDir *= sunDagNode.transformationMatrix(); lightDir *= renderGlobals->globalConversionMatrix; lightDir.normalize(); return TheaSDK::Normal3D(lightDir.x,lightDir.y,lightDir.z); } float sunDirX = 0.0f, sunDirY = 0.0f, sunDirZ = 1.0f; MPlug sunDirPlug = depFn.findPlug("sunDirection"); if (!sunDirPlug.isNull()) { sunDirX = sunDirPlug.child(0).asFloat(); sunDirY = sunDirPlug.child(1).asFloat(); sunDirZ = sunDirPlug.child(2).asFloat(); } return TheaSDK::Normal3D(sunDirX, sunDirY, sunDirZ); }
void dumpInfo( MObject fileNode, MFnDependencyNode& nodeFn, MObjectArray& nodePath ) { MObject currentNode; MObject fileAttr = nodeFn.attribute("fileTextureName"); MPlug plugToFile( fileNode, fileAttr ); MFnDependencyNode dgFn; MStatus stat; cerr << "Name: " << nodeFn.name() << endl; MObject fnameValue; stat = plugToFile.getValue( fnameValue ); if ( !stat ) { stat.perror("error getting value from plug"); } else { MFnStringData stringFn( fnameValue ); cerr << "Texture: " << stringFn.string() << endl; } cerr << "Path: "; for ( int i = nodePath.length()-1; i >= 0; i-- ) { currentNode = nodePath[i]; dgFn.setObject( currentNode ); cerr << dgFn.name() << "(" << dgFn.typeName() << ")"; if ( i > 0) cerr << " ->\n "; } cerr << endl; }
MStatus StrandLengthCount::doIt(const MArgList & args) { std::list<MObject> targets; MStatus status = ArgList_GetModelObjects(args, syntax(), "-b", targets); if (status != MStatus::kNotFound && status != MStatus::kSuccess) { HMEVALUATE_RETURN_DESCRIPTION("ArgList_GetModelObjects", status); } clearResult(); if (!targets.empty()) { for (std::list<MObject>::const_iterator it(targets.begin()); it != targets.end(); ++it) { Model::Base base(*it); Model::Strand strand(base); HPRINT("Calling with base: %s", base.getDagPath(status).fullPathName().asChar()); appendToResult(int(m_operation.length(strand))); } } else { MObjectArray objects; HMEVALUATE_RETURN(status = Model::Base::AllSelected(objects), status); for (unsigned int i = 0; i < objects.length(); ++i) { Model::Base base(objects[i]); Model::Strand strand(base); HPRINT("Calling with base: %s", base.getDagPath(status).fullPathName().asChar()); appendToResult(int(m_operation.length(strand))); } } return MStatus::kSuccess; }
// grab the current mesh and setup the polygon sets void Mesh::SetMesh(const MDagPath &dPath) { MObjectArray fPolygonSets; MObjectArray fPolygonComponents; MDagPath dagPath(dPath); polySets.clear(); MFnMesh fMesh = MFnMesh(dagPath); //Have to make the path include the shape below it so that //we can determine if the underlying shape node is instanced. //By default, dag paths only include transform nodes. dagPath.extendToShape(); //If the shape is instanced then we need to determine which instance this path refers to. int instanceNum = 0; if (dagPath.isInstanced()) instanceNum = dagPath.instanceNumber(); //Get the connected sets and members - these will be used to determine texturing of different faces if (!fMesh.getConnectedSetsAndMembers(instanceNum, fPolygonSets, fPolygonComponents, true)) { MGlobal::displayError("MFnMesh::getConnectedSetsAndMembers"); return; } unsigned int setCount = fPolygonSets.length(); if (setCount > 1) setCount--; for (unsigned int i=0; i < setCount; i++) polySets.push_back(PolygonSet(dagPath, fPolygonComponents[i], fPolygonSets[i])); }
MStatus GetSelectedObjectsOfType(MObjectArray & objects, MTypeId & type) { MStatus status; MSelectionList selectionList; if (!(status = MGlobal::getActiveSelectionList(selectionList))) { status.perror("MGlobal::getActiveSelectionList"); return status; } if (!(status = objects.clear())) { status.perror("MObjectArray::clear"); return status; } unsigned int selectionList_length = selectionList.length(&status); if (!status) { status.perror("MSelectionList::length"); return status; } for(unsigned int i = 0; i < selectionList_length; ++i) { //MDagPath dagPath; MObject object; if (!(status = selectionList.getDependNode(i, object))) { status.perror("MSelectionList::getDependNode"); return status; } MObject relative = GetObjectOrParentsOfType(object, type, status); if (!status) { status.perror("GetObjectOrParentsOfType"); return status; } if (relative != MObject::kNullObj) { /* * Make sure it's not already added */ bool contains = false; for(unsigned int i = 0; i < objects.length(); ++i) { if (objects[i] == object) { contains = true; break; } } if (!contains) objects.append(relative); } } return MStatus::kSuccess; }
bool isObjectInList(MObject obj, MObjectArray& objectArray) { for( uint oId = 0; oId < objectArray.length(); oId++) { if( objectArray[oId] == obj) return true; } return false; }
//------------------------------ void MaterialExporter::exportConnectedMaterials ( SceneElement* sceneElement ) { // If we have a external reference, we don't need to export the data here. if ( !sceneElement->getIsLocal() ) return; if ( !sceneElement->getIsExportNode () ) return; // Check if it is a mesh object and an export node if ( sceneElement->getType() == SceneElement::MESH ) { MDagPath dagPath = sceneElement->getPath(); // Attach a function set MStatus status; MFnMesh fnMesh ( dagPath.node(), &status ); if ( status != MStatus::kSuccess ) return; // Find how many shaders are used by this instance of the mesh MObjectArray shaders; MIntArray shaderIndices; unsigned instanceNumber = dagPath.instanceNumber(); fnMesh.getConnectedShaders ( instanceNumber, shaders, shaderIndices ); // Find the polygons that correspond to each materials and export them uint realShaderCount = ( uint ) shaders.length(); uint numShaders = ( uint ) std::max ( ( size_t ) 1, ( size_t ) shaders.length() ); for ( uint shaderPosition = 0; shaderPosition < numShaders; ++shaderPosition ) { if ( shaderPosition < realShaderCount ) { // Add shader-specific parameters (TexCoords sets). // Add symbolic name for the material used on this polygon set. MObject shadingEngine = shaders[shaderPosition]; exportMaterial ( shadingEngine ); } } } // recursive call for all the child elements for ( uint i=0; i<sceneElement->getChildCount(); ++i ) { SceneElement* childElement = sceneElement->getChild ( i ); exportConnectedMaterials ( childElement ); } }
void uniqueMObjectArray(MObjectArray& cleanMe) { MObjectArray tmpArray; for (uint i = 0; i < cleanMe.length(); i++) { bool found = false; for (uint k = 0; k < tmpArray.length(); k++) { if (cleanMe[i] == tmpArray[k]) { found = true; break; } } if (!found) tmpArray.append(cleanMe[i]); } cleanMe = tmpArray; }
void makeUniqueArray(MObjectArray& oa) { MObjectArray tmpArray; for (uint i = 0; i < oa.length(); i++) { bool found = false; for (uint k = 0; k < tmpArray.length(); k++) { if (oa[i] == tmpArray[k]) { found = true; break; } } if (!found) tmpArray.append(oa[i]); } oa = tmpArray; }
void HesperisIO::LsChildren(MObjectArray & dst, const int & maxCount, const MObject & oparent) { MFnDagNode ppf(oparent); for(unsigned i = 0; i <ppf.childCount(); i++) { dst.append(ppf.child(i) ); if(dst.length() >= maxCount) return; } }
void EntityNode::Unselect( MSelectionList& list ) { MObjectArray importNodes; GetImportNodes( importNodes ); u32 len = importNodes.length(); for( u32 i = 0; i < len; ++i ) { MGlobal::unselect( importNodes[i] ); } }
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; } }
//for this attribute on this node add the following layer nodes and plugs it's associated with void atomNodeWithAnimLayers::addPlugWithLayer(MPlug &attrPlug, MObjectArray &layers, MPlugArray &plugs) { if(plugs.length() == layers.length()) { MObject attrObj = attrPlug.attribute(); MFnAttribute fnLeafAttr (attrObj); std::string attrStd(std::string(fnLeafAttr.name().asChar())); PlugsAndLayers plugsAndLayers; for(unsigned int i =0; i < layers.length(); ++i) { if(plugs[i].isNull()==false) //it's possible to not have a plug for the specified layer { if(layers[i].hasFn (MFn::kDependencyNode)) { MFnDependencyNode fnNode (layers[i]); MString layerName = fnNode.name(); plugsAndLayers.mLayerNames.append(layerName); plugsAndLayers.mPlugs.append(plugs[i]); fAttrLayers[attrStd] = plugsAndLayers; } } } } }
void Exporter::OutputBlendShapes(MFnBlendShapeDeformer& fn, MObject& Base) { //Output info about the base shape MFnDependencyNode fnDep(Base); //Write base name cout << "\tBase " << fnDep.name().asChar() << endl; //attach the function set to the object unsigned int nWeights = fn.numWeights(); cout << "\t\tNumWeights " << nWeights << endl; MObjectArray targets; //Only want non-history items for (unsigned int i = 0; i != nWeights; ++i) { //fn.getBaseObjects(targets); //Get an array of target shapes fn.getTargets(Base, i + 1, targets); //cout << "Weight unimportant stuff " << fn.weightIndexList(l) << endl; cout << "\tCurrent Target: " << i << endl; //cout << "\tName:" << name().asChar() << endl; cout << "\t\tnumTargets " << targets.length() << endl; //output each target shape for (unsigned int j = 0; j < targets.length(); ++j) { outPutTarget(targets[j], Base); } } }
bool isIn(const MDagPath & dagPath, const MObject & referenceNode) { MDagPathArray rootDagPaths; MObjectArray subReferences; ReferenceManager::getRootObjects(referenceNode, rootDagPaths, subReferences); for (unsigned int i = 0; i < rootDagPaths.length(); ++i) { if (rootDagPaths[i] == dagPath) { return true; } } for (unsigned int i = 0; i < subReferences.length(); ++i) { if (isIn(dagPath, subReferences[i])) { return true; } } return false; }
void maTranslator::writeDefaultNodes(fstream& f) { // // For default nodes we don't write out a createNode statement, but we // still write added attributes and changed attribute values. // unsigned int numNodes = fDefaultNodes.length(); unsigned int i; for (i = 0; i < numNodes; i++) { writeNodeAttrs(f, fDefaultNodes[i], false); MFnDependencyNode nodeFn(fDefaultNodes[i]); nodeFn.setFlag(fAttrFlag, true); } }
MStatus Molecule3Cmd::undoIt() { MDGModifier dgMod; MFnDagNode dagFn; MObject child; unsigned int i; for( i=0; i < objTransforms.length(); i++ ) { // N.B. It is important to delete the child shape before // the transform node, otherwise Maya will crash. dagFn.setObject( objTransforms[i] ); child = dagFn.child( 0 ); dgMod.deleteNode( child ); dgMod.deleteNode( objTransforms[i] ); } return dgMod.doIt(); }
bool CoronaRenderer::isSunLight(std::shared_ptr<MayaObject> obj) { // a sun light has a transform connection to the coronaGlobals.sunLightConnection plug MObject coronaGlobals = objectFromName(MString("coronaGlobals")); MObjectArray nodeList; MStatus stat; getConnectedInNodes(MString("sunLightConnection"), coronaGlobals, nodeList); if( nodeList.length() > 0) { MObject sunObj = nodeList[0]; if(sunObj.hasFn(MFn::kTransform)) { MFnDagNode sunDagNode(sunObj); MObject sunDagObj = sunDagNode.child(0, &stat); if( sunDagObj == obj->mobject) return true; } } return false; }
MStatus ParameterisedHolder<B>::removeUnecessaryAttributes() { MObjectArray toRemove; MFnDependencyNode fnDN( B::thisMObject() ); for( unsigned i=0; i<fnDN.attributeCount(); i++ ) { MObject attr = fnDN.attribute( i ); MFnAttribute fnAttr( attr ); MString attrName = fnAttr.name(); if( 0==strncmp( attrName.asChar(), g_attributeNamePrefix.c_str(), g_attributeNamePrefix.size() ) ) { if( m_attributeNamesToParameters.find( fnAttr.name() )==m_attributeNamesToParameters.end() ) { MPlug plug( B::thisMObject(), attr ); plug.setLocked( false ); // we can't remove things if they're locked if( fnAttr.parent().isNull() ) { toRemove.append( attr ); } else { // we don't need to remove attributes which are the children // of compounds as they'll be removed when their parent is removed } } } } for( unsigned i=0; i<toRemove.length(); i++ ) { MStatus s = fnDN.removeAttribute( toRemove[i] ); if( !s ) { return s; } } return MStatus::kSuccess; }
//this function will pass in all anim layer objects found on a particular plug. since we want them to be //kept in order, but don't want ALL of the anim layers to be specified if they aren't used we bool atomAnimLayers::addAnimLayers(MObjectArray &layers) { if(mOrderedAnimLayerNames.length() > 0) { //first time called set up the mAnimLayers object array. if(mAnimLayers.length() != mOrderedAnimLayerNames.length()) { mAnimLayers.setLength(mOrderedAnimLayerNames.length()); MObject nullObject; //initialize with nulls for(unsigned int k = 0; k < mAnimLayers.length(); ++k) { mAnimLayers[k] = nullObject; } } } //if here we have the ordered name list and the anim layer object list //now we just need to set the objects passed in correctly for(unsigned int k = 0; k < layers.length(); ++k) { if(layers[k].hasFn (MFn::kDependencyNode)) { MFnDependencyNode fnNode (layers[k]); MString layerName = fnNode.name(); for(unsigned int z = 0; z < mOrderedAnimLayerNames.length();++z) { if(layerName == mOrderedAnimLayerNames[z]) { mAnimLayers[z] = layers[k]; break; } } } } return true; }
bool isSunLight(MObject& obj) { MObjectArray nodeList; MStatus stat; MObject sun = obj; if (obj.hasFn(MFn::kDirectionalLight)) { MFnDagNode sunDagNode(obj); sun = sunDagNode.parent(0); } getConnectedInNodes(MString("physicalSunConnection"), getRenderGlobalsNode(), nodeList); if (nodeList.length() > 0) { MObject sunObj = nodeList[0]; if (sunObj.hasFn(MFn::kTransform)) { if (sunObj == sun) return true; } } return false; }
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; }
bool atomExport::setUpAnimLayers(MSelectionList &sList,atomAnimLayers &animLayers, std::vector<atomNodeWithAnimLayers *> &nodesWithAnimLayers, std::set<std::string> &attrStrings, atomTemplateReader &templateReader) { unsigned int numObjects = sList.length(); nodesWithAnimLayers.resize(numObjects); bool somethingIsAnimLayered = false; for (unsigned int i = 0; i < numObjects; i++) { atomNodeWithAnimLayers *nodeWithLayer = NULL; //make sure it's a NULL, and preset it in case we skip this node nodesWithAnimLayers[i] = nodeWithLayer; MDagPath path; MObject node; if (sList.getDagPath (i, path) == MS::kSuccess) { MString name = path.partialPathName(); //if the name is in the template, only then write it out... if(templateReader.findNode(name)== false) { continue; } node = path.node(); } else if (sList.getDependNode (i, node) == MS::kSuccess) { if (!node.hasFn (MFn::kDependencyNode)) { continue; } MFnDependencyNode fnNode (node); MString name = fnNode.name(); if(templateReader.findNode(name)== false) { continue; } } if(node.isNull()==false) { MSelectionList localList; localList.add(node); MPlugArray animatablePlugs; MAnimUtil::findAnimatablePlugs(localList,animatablePlugs); unsigned int numPlugs = animatablePlugs.length(); MPlugArray cachedPlugs; for (unsigned int k = 0; k < numPlugs; k++) { MPlug plug = animatablePlugs[k]; MObjectArray layers; MPlugArray plugs; if(MAnimUtil::findAnimationLayers(plug,layers,plugs) && layers.length() > 0) { bool layerAdded = animLayers.addAnimLayers(layers); if(layerAdded) { if(nodeWithLayer == NULL) nodeWithLayer = new atomNodeWithAnimLayers(); nodeWithLayer->addPlugWithLayer(plug,layers,plugs); } somethingIsAnimLayered = somethingIsAnimLayered == false ? layerAdded : true; } } nodesWithAnimLayers[i] = nodeWithLayer; } } return somethingIsAnimLayered; }
TfToken usdWriteJob::writeVariants(const UsdPrim &usdRootPrim) { // Init parameters for filtering and setting the active variant std::string defaultModelingVariant; // Get the usdVariantRootPrimPath (optionally filter by renderLayer prefix) MayaPrimWriterPtr firstPrimWriterPtr = *mMayaPrimWriterList.begin(); std::string firstPrimWriterPathStr( firstPrimWriterPtr->getDagPath().fullPathName().asChar() ); std::replace( firstPrimWriterPathStr.begin(), firstPrimWriterPathStr.end(), '|', '/'); std::replace( firstPrimWriterPathStr.begin(), firstPrimWriterPathStr.end(), ':', '_'); // replace namespace ":" with "_" SdfPath usdVariantRootPrimPath(firstPrimWriterPathStr); usdVariantRootPrimPath = usdVariantRootPrimPath.GetPrefixes()[0]; // Create a new usdVariantRootPrim and reference the Base Model UsdRootPrim // This is done for reasons as described above under mArgs.usdModelRootOverridePath UsdPrim usdVariantRootPrim = mStage->DefinePrim(usdVariantRootPrimPath); TfToken defaultPrim = usdVariantRootPrim.GetName(); usdVariantRootPrim.GetReferences().AppendInternalReference(usdRootPrim.GetPath()); usdVariantRootPrim.SetActive(true); usdRootPrim.SetActive(false); // Loop over all the renderLayers for (unsigned int ir=0; ir < mRenderLayerObjs.length(); ++ir) { SdfPathTable<bool> tableOfActivePaths; MFnRenderLayer renderLayerFn( mRenderLayerObjs[ir] ); MString renderLayerName = renderLayerFn.name(); std::string variantName(renderLayerName.asChar()); // Determine default variant. Currently unsupported //MPlug renderLayerDisplayOrderPlug = renderLayerFn.findPlug("displayOrder", true); //int renderLayerDisplayOrder = renderLayerDisplayOrderPlug.asShort(); // The Maya default RenderLayer is also the default modeling variant if (mRenderLayerObjs[ir] == MFnRenderLayer::defaultRenderLayer()) { defaultModelingVariant=variantName; } // Make the renderlayer being looped the current one MGlobal::executeCommand(MString("editRenderLayerGlobals -currentRenderLayer ")+ renderLayerName, false, false); // == ModelingVariants == // Identify prims to activate // Put prims and parent prims in a SdfPathTable // Then use that membership to determine if a prim should be Active. // It has to be done this way since SetActive(false) disables access to all child prims. MObjectArray renderLayerMemberObjs; renderLayerFn.listMembers(renderLayerMemberObjs); std::vector< SdfPath > activePaths; for (unsigned int im=0; im < renderLayerMemberObjs.length(); ++im) { MFnDagNode dagFn(renderLayerMemberObjs[im]); MDagPath dagPath; dagFn.getPath(dagPath); dagPath.extendToShape(); SdfPath usdPrimPath; if (!TfMapLookup(mDagPathToUsdPathMap, dagPath, &usdPrimPath)) { continue; } usdPrimPath = usdPrimPath.ReplacePrefix(usdPrimPath.GetPrefixes()[0], usdVariantRootPrimPath); // Convert base to variant usdPrimPath tableOfActivePaths[usdPrimPath] = true; activePaths.push_back(usdPrimPath); //UsdPrim usdPrim = mStage->GetPrimAtPath(usdPrimPath); //usdPrim.SetActive(true); } if (!tableOfActivePaths.empty()) { { // == BEG: Scope for Variant EditContext // Create the variantSet and variant UsdVariantSet modelingVariantSet = usdVariantRootPrim.GetVariantSets().AppendVariantSet("modelingVariant"); modelingVariantSet.AppendVariant(variantName); modelingVariantSet.SetVariantSelection(variantName); // Set the Edit Context UsdEditTarget editTarget = modelingVariantSet.GetVariantEditTarget(); UsdEditContext editContext(mStage, editTarget); // == Activate/Deactivate UsdPrims UsdPrimRange it = UsdPrimRange::AllPrims(mStage->GetPseudoRoot()); std::vector<UsdPrim> primsToDeactivate; for ( ; it; ++it) { UsdPrim usdPrim = *it; // For all xformable usdPrims... if (usdPrim && usdPrim.IsA<UsdGeomXformable>()) { bool isActive=false; for (size_t j=0;j<activePaths.size();j++) { //primPathD.HasPrefix(primPathA); SdfPath activePath=activePaths[j]; if (usdPrim.GetPath().HasPrefix(activePath) || activePath.HasPrefix(usdPrim.GetPath())) { isActive=true; break; } } if (isActive==false) { primsToDeactivate.push_back(usdPrim); it.PruneChildren(); } } } // Now deactivate the prims (done outside of the UsdPrimRange // so not to modify the iterator while in the loop) for ( UsdPrim const& prim : primsToDeactivate ) { prim.SetActive(false); } } // == END: Scope for Variant EditContext } } // END: RenderLayer iterations // Set the default modeling variant UsdVariantSet modelingVariantSet = usdVariantRootPrim.GetVariantSet("modelingVariant"); if (modelingVariantSet.IsValid()) { modelingVariantSet.SetVariantSelection(defaultModelingVariant); } return defaultPrim; }
MStatus MayaFileTranslator::writer( const MFileObject& file, const MString& options, FileAccessMode mode){ //-------------------détection des options transmises par le script MEL--------------- // this will store our option strings MStringArray optionList; // seperate the option string options.split(' ', optionList); // check all of the options int len = optionList.length(); for( int i = 0; i < len; ++i ){ MString Option = optionList[i]; // if we recognised option 1 if( Option == "vertexcolorFlag" ) { // check for true or false if(optionList[++i]=="0") Flags.vertex_colors=0; else Flags.vertex_colors=1; } // if we recognised our second option if( Option == "vertexnormalFlag" ) { // check for true or false if(optionList[++i]=="0") Flags.Normals=0; else Flags.Normals=1; } // if we recognised our third option if( Option == "brushFX" ) { // check for true or false if(optionList[++i]=="0") Flags.use_vertex_colors=1; else Flags.use_vertex_colors=0; } } //----------------------------------fin------------------------ //export Selected Objects if(mode == kExportActiveAccessMode) { //liste des objets sélectionnés MSelectionList selection; MGlobal::getActiveSelectionList( selection ); //MStringArray strings; //MDagPath dagPath; MObject components; MDagPath path; //----- // int temp; //MGlobal::displayInfo("Début exportation des objets sélectionnés"); // ouverture du fichier [BB3D] MString output_filename = file.fullName(); ::output.open(output_filename.asChar(),ios::out |ios::binary); // ecriture header fichier ::output << "BB3D"; // mise en place du Header fichier B3D StartChunck(); // sauv garde de la position du début de fichier //write_int(1);// mise en place d'une valeur entière quelconque pour mise en place ultérieure de la longeur du fichier write_int(1);//écriture de la version BB3D #ifdef OLD_TEXS // écriture des textures si présentent [TEXS]|detection des textures à enregistrer| + fermeture texs ::output << "TEXS";//header Brush StartChunck(); OutputTextures(selection); EndChunck(); // écriture des matériaux [BRUS]|detection des materiaux à enregistrer| +fermeture brus //Matid.clear(); OutputMaterials(selection); #else //nouvelles textures #endif //------------------------------------fin materials---------------------------------- #ifdef SCENE_ROOT // algo des nodes [NODE] réplication de la hierarchie, ::output << "NODE"; // mise en place du Header fichier B3D StartChunck(); //write_int(1);// mise en place d'une valeur quelconque ::output << "Scene Root";//nom du Node ::output << char(0x00);//fin de chaîne //écriture des coordonnées spatiales //transaltion write_float(0);// translation x write_float(0);// translation y write_float(0);// translation z write_float(1);//scale x write_float(1);//scale y write_float(1);//scale z write_float(0);// rotation x write_float(0);// rotation y write_float(0);// rotation z write_float(0);// rotation w #else #endif int pos_objet=0,pos_nouvel_objet; MString nom_objet_precedent; // create an iterator to go through all transforms //MItDag it(MItDag::depth, MFn::kTransform); MItDag it(MItDag::kDepthFirst, MFn::kTransform); // keep looping until done int position_hierarchie=0; int pos=0; while(!it.isDone()) { MString temp; MDagPath path; it.getPath(path); MFnTransform trans(path); MObject obj=it.item(); MStringArray chemin_split; MString chemin=path.fullPathName(); chemin.split((char)'|',chemin_split); pos=chemin_split.length(); //temp=pos; //MGlobal::displayInfo(temp); if(obj.apiType()== MFn::kTransform && path.child(0).apiType()== MFn::kMesh){ //MGlobal::displayInfo("Transform trouvé avec child Kmesh"); //écriture du node avec transform //incrément de la hierarchie if(pos<position_hierarchie || pos==position_hierarchie){ //MGlobal::displayInfo("fermeture des nodes précédents"); for(int i=position_hierarchie;i>pos-1;i--){ //temp = i; //MGlobal::displayInfo(temp); EndChunck(); }//fin for }//fin if //MGlobal::displayInfo("Ouverture node"); ::output << "NODE"; // mise en place du Header node StartChunck(); MString nom_objet; nom_objet=chemin_split[chemin_split.length()-1]; ::output << nom_objet.substring(0,nom_objet.length());//nom du Node ::output << char(0x00);//caractêre de fin de chaîne MVector Translation; // get the transforms local translation Translation = trans.getTranslation(MSpace::kTransform); float temp=(float)Translation.x; //écriture des coordonnées spaciales //transaltion write_float(temp);// translation x temp=(float)Translation.y; write_float(temp);// translation y temp=-(float)Translation.z; write_float(temp);// translation z double scale[3]; trans.getScale(scale); temp=(float)scale[0]; write_float(temp); temp=(float)scale[1]; write_float(temp); temp=(float)scale[2]; write_float(temp); MQuaternion Rotation; trans.getRotation(Rotation,MSpace::kTransform); temp=(float)Rotation.w; write_float(temp); temp=(float)Rotation.x; write_float(temp); temp=(float)Rotation.y; write_float(temp); temp=(float)Rotation.z; write_float(temp); path.getPath(path); if(selection.hasItem(path)!=MStatus::kSuccess){ //MGlobal::displayInfo("présent dans la liste de selection"); //---------exportation du mesh //mais avec des nodes vides, pour les mesh non sélectionnés //----------------------------ecriture mesh si objet polygonal présent ::output << "MESH"; // mise en place du Header mesh StartChunck(); MPointArray vertexArray;// coordonnées des point format double x,y,z; MIntArray vertexList;// stockage des indexs des points pour les triangles MVector Normal;//stockage d'une normal d'un vertex //----------------------coordonnées Vertexs (normal & color si présent et demandés) //master brush //write_int(0xffffffff); write_int(-1);//-1 master brush MFnMesh meshFn(path.child(0)); // crée une fonction pour le mesh MItMeshVertex polyperVertex(path, MObject::kNullObj);// crée une fonction pour le mesh , mais avec les fonctions de itmesh //récupération des coordonnées des points //obtient les coordonnées des vertex en mode global //meshFn.getPoints(vertexArray,MSpace::kObject); meshFn.getPoints(vertexArray,MSpace::kTransform); //MFloatArray uArray; //MFloatArray vArray; //meshFn.getUVs(uArray,vArray);//getUVs( MFloatArray& uArray, MFloatArray& vArray,const MString * uvSet = NULL ) MIntArray uvCounts,uvIds; meshFn.getAssignedUVs(uvCounts,uvIds,0); //ecriture VRTS ::output<<"VRTS"; StartChunck(); //flags 0=none just vertices coords 1=normal values present, 2=rgba values present //The way the flags work, is that you combine them. //1 = Vertex Normal //2 = Vertex Color //3 = Vertex Normal + Color int flag_normal_colors=0; //info = "Normals "; //info += Flags.Normals; //Affich(info); //info = "vertex colors "; //info += Flags.vertex_colors; //Affich(info); flag_normal_colors = Flags.Normals+((Flags.use_vertex_colors && Flags.vertex_colors)*2); //info = flag_normal_colors; //Affich(info); write_int(flag_normal_colors);//présence normale //int tex_coord_sets ;texture coords per vertex (eg: 1 for simple U/V) max=8 write_int(1);//uv simple // int tex_coord_set_size ;components per set (eg: 2 for simple U/V) max=4 write_int(2);//2 coordonées textures float x,y,z,normx,normy,normz;//,normx,normy,normz; for (unsigned int i=0;i<vertexArray.length();i++){ x =float(vertexArray[i].x); // - pour replacer l'axe X dans le sens de celui de blitz y =float(vertexArray[i].y); z =-float(vertexArray[i].z);// - //vertices coords write_float(x); write_float(y); write_float(z); //récupère la normale du point if(flag_normal_colors==1 || flag_normal_colors==3){ meshFn.getVertexNormal(i, Normal ,MSpace::kObject); normx=float(Normal.x); normy=float(Normal.y); normz=float(Normal.z); write_float(normx); write_float(normy); write_float(normz); } //----------------------------------------- //vertex_colors_present=1; if (flag_normal_colors == 2 || flag_normal_colors==3){ MStringArray colorsets; MColorArray color; //status = meshFn.getColorSetNames(colorsets); meshFn.getColorSetNames(colorsets); MColor couleur; MString colorset = colorsets[0]; //récupère la couleur moyenne des faces connectés au point meshFn.getVertexColors(color,&colorset); //polyperVertex.getColor //int a; //meshFn.getColor(a,couleur); //meshFn.getColors(color); couleur=color[i]; float col=float(couleur.r); //R ::output.write((char*)&couleur.r,sizeof(couleur.r)); //write_float(col); col=float(couleur.g); //G ::output.write((char*)&couleur.g,sizeof(couleur.g)); //write_float(col); col=float(couleur.b); //B ::output.write((char*)&couleur.b,sizeof(couleur.b)); //write_float(col); col=float(couleur.a); //Alpha ::output.write((char*)&couleur.a,sizeof(couleur.a)); //write_float(col); } //----------------------------------------- //float tempo; float u,v; MFloatArray uArray; MFloatArray vArray; MIntArray FaceIds; polyperVertex.getUVs(uArray,vArray,FaceIds); //meshFn.getUV(i*2,u,v); u=uArray[0]; v=vArray[0]; //tempo = uArray[0]; //write_float(tempo); //tempo = vArray[0]; //write_float(tempo); write_float(u); write_float(-v); polyperVertex.next(); }//fin for //-----------------fermeture coordonées Vertex EndChunck(); // ----------------------------------export des triangles #ifdef OLD_TRIS //ecriture TRIS ::output<<"TRIS"; StartChunck(); //brush ID write_int(-1);//write_int(0); //MItMeshPolygon itPolygon( path, MObject::kNullObj ); MItMeshPolygon itPolygon(path.child(0)); for ( /* nothing */; !itPolygon.isDone(); itPolygon.next() ) { // Get triangulation of this poly. int numTriangles; itPolygon.numTriangles(numTriangles); while ( numTriangles-- ) { //MGlobal::displayInfo(" triangle"); MStatus status; MIntArray polygonVertices; itPolygon.getVertices( polygonVertices ); MPointArray nonTweaked; // object-relative vertex indices for each triangle MIntArray triangleVertices; // face-relative vertex indices for each triangle MIntArray localIndex; status = itPolygon.getTriangle( numTriangles, nonTweaked, triangleVertices, MSpace::kObject ); if ( status == MS::kSuccess ) { //traitement du triangle // Get face-relative vertex indices for this triangle //int temp=triangleVertices[0]; write_int(triangleVertices[0]); write_int(triangleVertices[2]); write_int(triangleVertices[1]); //::output.write((char*)&triangleVertices[0],sizeof(triangleVertices[0])); //::output.write((char*)&triangleVertices[2],sizeof(triangleVertices[2])); //::output.write((char*)&triangleVertices[1],sizeof(triangleVertices[1])); } // fin if };// fin while }; //fin for EndChunck(); #else unsigned int instancenumbers; MObjectArray shaders; MIntArray indices; //MFnMesh Fn(path.instanceNumber); meshFn.getConnectedShaders(instancenumbers,shaders,indices); MString info="shaders.lenght "; info += shaders.length(); Affich(info); for (int i=-1;i<shaders.length();i++){//création de tris en fonction du nombre de brush appliqué //___________ouput tris________ info = "shader "; info += i; Affich(info); //ecriture TRIS ::output<<"TRIS"; StartChunck(); //trouver le brush id par rapport à matid //recup nom shader et compare à matid MString nameshader; nameshader=GetShaderName(shaders[i]); info = "Matid id lenght"; info += Matid.length(); Affich(info); int BrushId=0; for (int b=0;b<Matid.length();b++){ if (nameshader==Matid[b]){ BrushId=b; } } //brush ID write_int(BrushId); //write_int(-1);//default info= "BrushId "; info += BrushId; Affich(info); info = Matid[BrushId]; Affich(info); MItMeshPolygon itPolygon(path.child(0)); int d=0; for ( /* nothing */; !itPolygon.isDone(); itPolygon.next() ) { nameshader=GetShaderName(shaders[indices[d]]); if(nameshader==Matid[BrushId]){ // Get triangulation of this poly. int numTriangles; itPolygon.numTriangles(numTriangles); while ( numTriangles-- ) { //MGlobal::displayInfo(" triangle"); MStatus status; MIntArray polygonVertices; itPolygon.getVertices( polygonVertices ); MPointArray nonTweaked; // object-relative vertex indices for each triangle MIntArray triangleVertices; // face-relative vertex indices for each triangle MIntArray localIndex; status = itPolygon.getTriangle( numTriangles, nonTweaked, triangleVertices, MSpace::kObject ); if ( status == MS::kSuccess ) { write_int(triangleVertices[0]); write_int(triangleVertices[2]); write_int(triangleVertices[1]); } // fin if };// fin while } d++; } for (int i=0;i<indices.length();i++){ //info = " indice "; //info += indices[i]; //Affich(info); nameshader=GetShaderName(shaders[indices[i]]); if(nameshader==Matid[BrushId]){ //info=nameshader; //Affich(info); //*********************ecrire triangle******* } } EndChunck(); } //for (int i=0;i<Matid.length();i++){ // info = Matid[i]; // Affich(info); //} //Affich("fin objet"); #endif //---------------------fermeture mesh EndChunck(); //------------------------------------------------------------ } position_hierarchie=pos; } // move on to next node it.next(); }//fin while //fermeture du node //fermeture fichier //fermeture de tous les nodes ouverts //for (int i=posfichier.length();i>0;i--){ #ifdef SCENE_ROOT EndChunck(); #else #endif //} //écriture de la longueur du fichier output.close(); Matid.clear(); Texid.clear(); nb_Tex_by_Brush.clear(); Texids_by_brush.clear(); } else //export all polygonal scene objects { } return MS::kSuccess; }
MStatus AlembicExportCommand::doIt(const MArgList &args) { ESS_PROFILE_SCOPE("AlembicExportCommand::doIt"); MStatus status = MS::kFailure; MTime currentAnimStartTime = MAnimControl::animationStartTime(), currentAnimEndTime = MAnimControl::animationEndTime(), oldCurTime = MAnimControl::currentTime(), curMinTime = MAnimControl::minTime(), curMaxTime = MAnimControl::maxTime(); MArgParser argData(syntax(), args, &status); if (argData.isFlagSet("help")) { // TODO: implement help for this command // MGlobal::displayInfo(util::getHelpText()); return MS::kSuccess; } unsigned int jobCount = argData.numberOfFlagUses("jobArg"); MStringArray jobStrings; if (jobCount == 0) { // TODO: display dialog MGlobal::displayError("[ExocortexAlembic] No jobs specified."); MPxCommand::setResult( "Error caught in AlembicExportCommand::doIt: no job specified"); return status; } else { // get all of the jobstrings for (unsigned int i = 0; i < jobCount; i++) { MArgList jobArgList; argData.getFlagArgumentList("jobArg", i, jobArgList); jobStrings.append(jobArgList.asString(0)); } } // create a vector to store the jobs std::vector<AlembicWriteJob *> jobPtrs; double minFrame = 1000000.0; double maxFrame = -1000000.0; double maxSteps = 1; double maxSubsteps = 1; // init the curve accumulators AlembicCurveAccumulator::Initialize(); try { // for each job, check the arguments bool failure = false; for (unsigned int i = 0; i < jobStrings.length(); ++i) { double frameIn = 1.0; double frameOut = 1.0; double frameSteps = 1.0; double frameSubSteps = 1.0; MString filename; bool purepointcache = false; bool normals = true; bool uvs = true; bool facesets = true; bool bindpose = true; bool dynamictopology = false; bool globalspace = false; bool withouthierarchy = false; bool transformcache = false; bool useInitShadGrp = false; bool useOgawa = false; // Later, will need to be changed! MStringArray objectStrings; std::vector<std::string> prefixFilters; std::set<std::string> attributes; std::vector<std::string> userPrefixFilters; std::set<std::string> userAttributes; MObjectArray objects; std::string search_str, replace_str; // process all tokens of the job MStringArray tokens; jobStrings[i].split(';', tokens); for (unsigned int j = 0; j < tokens.length(); j++) { MStringArray valuePair; tokens[j].split('=', valuePair); if (valuePair.length() != 2) { MGlobal::displayWarning( "[ExocortexAlembic] Skipping invalid token: " + tokens[j]); continue; } const MString &lowerValue = valuePair[0].toLowerCase(); if (lowerValue == "in") { frameIn = valuePair[1].asDouble(); } else if (lowerValue == "out") { frameOut = valuePair[1].asDouble(); } else if (lowerValue == "step") { frameSteps = valuePair[1].asDouble(); } else if (lowerValue == "substep") { frameSubSteps = valuePair[1].asDouble(); } else if (lowerValue == "normals") { normals = valuePair[1].asInt() != 0; } else if (lowerValue == "uvs") { uvs = valuePair[1].asInt() != 0; } else if (lowerValue == "facesets") { facesets = valuePair[1].asInt() != 0; } else if (lowerValue == "bindpose") { bindpose = valuePair[1].asInt() != 0; } else if (lowerValue == "purepointcache") { purepointcache = valuePair[1].asInt() != 0; } else if (lowerValue == "dynamictopology") { dynamictopology = valuePair[1].asInt() != 0; } else if (lowerValue == "globalspace") { globalspace = valuePair[1].asInt() != 0; } else if (lowerValue == "withouthierarchy") { withouthierarchy = valuePair[1].asInt() != 0; } else if (lowerValue == "transformcache") { transformcache = valuePair[1].asInt() != 0; } else if (lowerValue == "filename") { filename = valuePair[1]; } else if (lowerValue == "objects") { // try to find each object valuePair[1].split(',', objectStrings); } else if (lowerValue == "useinitshadgrp") { useInitShadGrp = valuePair[1].asInt() != 0; } // search/replace else if (lowerValue == "search") { search_str = valuePair[1].asChar(); } else if (lowerValue == "replace") { replace_str = valuePair[1].asChar(); } else if (lowerValue == "ogawa") { useOgawa = valuePair[1].asInt() != 0; } else if (lowerValue == "attrprefixes") { splitListArg(valuePair[1], prefixFilters); } else if (lowerValue == "attrs") { splitListArg(valuePair[1], attributes); } else if (lowerValue == "userattrprefixes") { splitListArg(valuePair[1], userPrefixFilters); } else if (lowerValue == "userattrs") { splitListArg(valuePair[1], userAttributes); } else { MGlobal::displayWarning( "[ExocortexAlembic] Skipping invalid token: " + tokens[j]); continue; } } // now check the object strings for (unsigned int k = 0; k < objectStrings.length(); k++) { MSelectionList sl; MString objectString = objectStrings[k]; sl.add(objectString); MDagPath dag; for (unsigned int l = 0; l < sl.length(); l++) { sl.getDagPath(l, dag); MObject objRef = dag.node(); if (objRef.isNull()) { MGlobal::displayWarning("[ExocortexAlembic] Skipping object '" + objectStrings[k] + "', not found."); break; } // get all parents MObjectArray parents; // check if this is a camera bool isCamera = false; for (unsigned int m = 0; m < dag.childCount(); ++m) { MFnDagNode child(dag.child(m)); MFn::Type ctype = child.object().apiType(); if (ctype == MFn::kCamera) { isCamera = true; break; } } if (dag.node().apiType() == MFn::kTransform && !isCamera && !globalspace && !withouthierarchy) { MDagPath ppath = dag; while (!ppath.node().isNull() && ppath.length() > 0 && ppath.isValid()) { parents.append(ppath.node()); if (ppath.pop() != MStatus::kSuccess) { break; } } } else { parents.append(dag.node()); } // push all parents in while (parents.length() > 0) { bool found = false; for (unsigned int m = 0; m < objects.length(); m++) { if (objects[m] == parents[parents.length() - 1]) { found = true; break; } } if (!found) { objects.append(parents[parents.length() - 1]); } parents.remove(parents.length() - 1); } // check all of the shapes below if (!transformcache) { sl.getDagPath(l, dag); for (unsigned int m = 0; m < dag.childCount(); m++) { MFnDagNode child(dag.child(m)); if (child.isIntermediateObject()) { continue; } objects.append(child.object()); } } } } // check if we have incompatible subframes if (maxSubsteps > 1.0 && frameSubSteps > 1.0) { const double part = (frameSubSteps > maxSubsteps) ? (frameSubSteps / maxSubsteps) : (maxSubsteps / frameSubSteps); if (abs(part - floor(part)) > 0.001) { MString frameSubStepsStr, maxSubstepsStr; frameSubStepsStr.set(frameSubSteps); maxSubstepsStr.set(maxSubsteps); MGlobal::displayError( "[ExocortexAlembic] You cannot combine substeps " + frameSubStepsStr + " and " + maxSubstepsStr + " in one export. Aborting."); return MStatus::kInvalidParameter; } } // remember the min and max values for the frames if (frameIn < minFrame) { minFrame = frameIn; } if (frameOut > maxFrame) { maxFrame = frameOut; } if (frameSteps > maxSteps) { maxSteps = frameSteps; } if (frameSteps > 1.0) { frameSubSteps = 1.0; } if (frameSubSteps > maxSubsteps) { maxSubsteps = frameSubSteps; } // check if we have a filename if (filename.length() == 0) { MGlobal::displayError("[ExocortexAlembic] No filename specified."); for (size_t k = 0; k < jobPtrs.size(); k++) { delete (jobPtrs[k]); } MPxCommand::setResult( "Error caught in AlembicExportCommand::doIt: no filename " "specified"); return MStatus::kFailure; } // construct the frames MDoubleArray frames; { const double frameIncr = frameSteps / frameSubSteps; for (double frame = frameIn; frame <= frameOut; frame += frameIncr) { frames.append(frame); } } AlembicWriteJob *job = new AlembicWriteJob(filename, objects, frames, useOgawa, prefixFilters, attributes, userPrefixFilters, userAttributes); job->SetOption("exportNormals", normals ? "1" : "0"); job->SetOption("exportUVs", uvs ? "1" : "0"); job->SetOption("exportFaceSets", facesets ? "1" : "0"); job->SetOption("exportInitShadGrp", useInitShadGrp ? "1" : "0"); job->SetOption("exportBindPose", bindpose ? "1" : "0"); job->SetOption("exportPurePointCache", purepointcache ? "1" : "0"); job->SetOption("exportDynamicTopology", dynamictopology ? "1" : "0"); job->SetOption("indexedNormals", "1"); job->SetOption("indexedUVs", "1"); job->SetOption("exportInGlobalSpace", globalspace ? "1" : "0"); job->SetOption("flattenHierarchy", withouthierarchy ? "1" : "0"); job->SetOption("transformCache", transformcache ? "1" : "0"); // check if the search/replace strings are valid! if (search_str.length() ? !replace_str.length() : replace_str.length()) // either search or // replace string is // missing or empty! { ESS_LOG_WARNING( "Missing search or replace parameter. No strings will be " "replaced."); job->replacer = SearchReplace::createReplacer(); } else { job->replacer = SearchReplace::createReplacer(search_str, replace_str); } // check if the job is satifsied if (job->PreProcess() != MStatus::kSuccess) { MGlobal::displayError("[ExocortexAlembic] Job skipped. Not satisfied."); delete (job); failure = true; break; } // push the job to our registry MGlobal::displayInfo("[ExocortexAlembic] Using WriteJob:" + jobStrings[i]); jobPtrs.push_back(job); } if (failure) { for (size_t k = 0; k < jobPtrs.size(); k++) { delete (jobPtrs[k]); } return MS::kFailure; } // compute the job count unsigned int jobFrameCount = 0; for (size_t i = 0; i < jobPtrs.size(); i++) jobFrameCount += (unsigned int)jobPtrs[i]->GetNbObjects() * (unsigned int)jobPtrs[i]->GetFrames().size(); // now, let's run through all frames, and process the jobs const double frameRate = MTime(1.0, MTime::kSeconds).as(MTime::uiUnit()); const double incrSteps = maxSteps / maxSubsteps; double nextFrame = minFrame + incrSteps; for (double frame = minFrame; frame <= maxFrame; frame += incrSteps, nextFrame += incrSteps) { MAnimControl::setCurrentTime(MTime(frame / frameRate, MTime::kSeconds)); MAnimControl::setAnimationEndTime( MTime(nextFrame / frameRate, MTime::kSeconds)); MAnimControl::playForward(); // this way, it forces Maya to play exactly // one frame! and particles are updated! AlembicCurveAccumulator::StartRecordingFrame(); for (size_t i = 0; i < jobPtrs.size(); i++) { MStatus status = jobPtrs[i]->Process(frame); if (status != MStatus::kSuccess) { MGlobal::displayError("[ExocortexAlembic] Job aborted :" + jobPtrs[i]->GetFileName()); for (size_t k = 0; k < jobPtrs.size(); k++) { delete (jobPtrs[k]); } restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime, curMinTime, curMaxTime); return status; } } AlembicCurveAccumulator::StopRecordingFrame(); } } catch (...) { MGlobal::displayError( "[ExocortexAlembic] Jobs aborted, force closing all archives!"); for (std::vector<AlembicWriteJob *>::iterator beg = jobPtrs.begin(); beg != jobPtrs.end(); ++beg) { (*beg)->forceCloseArchive(); } restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime, curMinTime, curMaxTime); MPxCommand::setResult("Error caught in AlembicExportCommand::doIt"); status = MS::kFailure; } MAnimControl::stop(); AlembicCurveAccumulator::Destroy(); // restore the animation start/end time and the current time! restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime, curMinTime, curMaxTime); // delete all jobs for (size_t k = 0; k < jobPtrs.size(); k++) { delete (jobPtrs[k]); } // remove all known archives deleteAllArchives(); return status; }