void AbcWriteJob::setup(double iFrame, MayaTransformWriterPtr iParent, util::GetMembersMap& gmMap) { MStatus status; // short-circuit if selection flag is on but this node isn't actively // selected if (mArgs.useSelectionList && !mSList.hasItem(mCurDag)) return; MObject ob = mCurDag.node(); MFnDependencyNode fnDepNode(ob, &status); bool bSolvedState = fnDepNode.typeName() == "bulletRigidCollection"; // skip all intermediate nodes (and their children) if (util::isIntermediate(ob)) { if (!bSolvedState) { return; } } // skip nodes that aren't renderable (and their children) if (mArgs.excludeInvisible && !util::isRenderable(ob)) { return; } if ( bSolvedState ) { // the motionstates are held on the initialstate node at the moment if (status != MS::kSuccess) { MString msg = "Initialize transform collection node "; msg += mCurDag.fullPathName(); msg += " failed, skipping."; MGlobal::displayWarning(msg); return; } MayaTransformCollectionWriterPtr transCol; // transformcollections always parented to the root case Alembic::Abc::OObject obj = mRoot.getTop(); transCol = MayaTransformCollectionWriterPtr(new MayaTransformCollectionWriter( obj, mCurDag, mTransTimeIndex, mArgs)); mTransColList.push_back(transCol); mStats.mTransColNum++; AttributesWriterPtr attrs = transCol->getAttrs(); if (attrs) { if (mTransTimeIndex != 0 && attrs->isAnimated()) mTransColAttrList.push_back(attrs); } } else if (ob.hasFn(MFn::kTransform)) { MFnTransform fnTrans(ob, &status); if (status != MS::kSuccess) { MString msg = "Initialize transform node "; msg += mCurDag.fullPathName(); msg += " failed, skipping."; MGlobal::displayWarning(msg); return; } MayaTransformWriterPtr trans; // parented to the root case if (iParent == NULL) { Alembic::Abc::OObject obj = mRoot.getTop(); trans = MayaTransformWriterPtr(new MayaTransformWriter( obj, mCurDag, mTransTimeIndex, mArgs)); } else { trans = MayaTransformWriterPtr(new MayaTransformWriter( *iParent, mCurDag, mTransTimeIndex, mArgs)); } if (trans->isAnimated() && mTransTimeIndex != 0) { mTransList.push_back(trans); mStats.mTransAnimNum++; } else mStats.mTransStaticNum++; AttributesWriterPtr attrs = trans->getAttrs(); if (mTransTimeIndex != 0 && attrs->isAnimated()) mTransAttrList.push_back(attrs); // loop through the children, making sure to push and pop them // from the MDagPath unsigned int numChild = mCurDag.childCount(); for (unsigned int i = 0; i < numChild; ++i) { mCurDag.push(mCurDag.child(i)); setup(iFrame, trans, gmMap); mCurDag.pop(); } } else { MString warn = mCurDag.fullPathName() + " is an unsupported type of "; warn += ob.apiTypeStr(); MGlobal::displayWarning(warn); } }
MStatus SplitFromImage::doIt(const MArgList& args) { MSelectionList list; MGlobal::getActiveSelectionList(list); MObject node; MFnDependencyNode depFn; MStringArray types; MString name; MDagPath dag; for( MItSelectionList iter( list ); !iter.isDone(); iter.next() ) { // Print the types and function sets of all of the objects iter.getDependNode( node ); depFn.setObject( node ); name = depFn.name(); MGlobal::getFunctionSetList( node, types ); cout << "Name: " << name.asChar() << endl; cout << "Type: " << node.apiTypeStr() << endl; /*cout << "Function Sets: "; for(unsigned int i = 0; i < types.length(); i++ ) { if ( i > 0 ) cout << ", "; cout << types[i].asChar(); } cout << endl << endl;*/ // Check if object has a MDagPath if(iter.getDagPath( dag ) == MS::kSuccess) { // Get the MFnMesh from the MDagPath dag.extendToShape(); MFnMesh mesh(dag.node()); //MPointArray points; //mesh.getPoints(points); //MFloatArray uPoints; //MFloatArray vPoints; //mesh.getUVs(uPoints, vPoints); //for (unsigned int i = 0; i < uPoints.length(); i++) { // cout << "uPoints[" << i << "]: " << uPoints[i] << endl; //} //for(unsigned int i = 0; i < points.length(); i++) { // cout << "Points[" << i << "]: " << points[i] << endl; //} if (splitFromBinaryImage(mesh, args.asString(0)) == MS::kSuccess) { cout << "Splitted image!" << endl; } else { cout << "Could not split image!" << endl; } } else { cout << "Selected object has no MDagPath!" << endl << endl; } } return MS::kSuccess; }
/** * Export Maya DAG node */ osg::ref_ptr<osg::Node> DAGNode::exporta(MDagPath &dp) { // Get the node from the path MObject node = dp.node(); MFnDependencyNode dnodefn(node); bool visible; dnodefn.findPlug("visibility").getValue(visible); if ( !visible ) { return NULL; } osg::ref_ptr<osg::Node> osgnode; #ifdef _DEBUG std::cout << "Exporting node " << node.apiTypeStr() << " (" << dnodefn.name().asChar() << ")" << std::endl; #endif // Check what type of node it is // GROUPS if( node.hasFn( MFn::kWorld ) || node.hasFn( MFn::kTransform ) ){ return Group::exporta(dp); } // POLYGON MESHES (AND CUSTOM NODES) else if( node.hasFn( MFn::kMesh ) ){ // Ignore Intermediate Objects ( Object Display ), mostly source of History and unwanted if( dnodefn.findPlug( "intermediateObject" ).asBool() ) return NULL ; //return MeshOld::exporta(node); return Mesh::exporta(dp); } // NURBS else if( node.hasFn( MFn::kNurbsSurface ) ){ // Geometry (NURBS) std::cout << "WARNING! This plug-in does not support NURBS by now, so you must convert " << dp.fullPathName().asChar() << " to polygons" << std::endl; return NULL; } // CAMERAS else if( node.hasFn( MFn::kCamera ) ){ return Camera::exporta(node); } // LIGTHS else if( node.hasFn( MFn::kAmbientLight ) || node.hasFn( MFn::kAreaLight ) || node.hasFn( MFn::kVolumeLight ) ) { std::cout << "WARNING. The exporter does not support ambient, area or volume lights" << std::endl; return NULL; } else if( node.hasFn( MFn::kPointLight ) ) { return PointLight::exporta(node); } else if( node.hasFn( MFn::kDirectionalLight ) ) { return DirectionalLight::exporta(node); } else if( node.hasFn( MFn::kSpotLight ) ) { return SpotLight::exporta(node); } // PARTICLES else if( node.hasFn( MFn::kParticle ) ) { return Particle::exporta(node); } else if( node.hasFn( MFn::kNParticle ) ) { return NParticle::exporta(node); } // IGNORED TYPES OF NODE (groundplane, etc ...) else if( node.hasFn( MFn::kGroundPlane ) || node.hasFn( MFn::kLocator ) ){ return NULL; } else { std::cout << "ERROR. Unknown node type : " << dp.fullPathName().asChar() << "(" << node.apiTypeStr() << "). Ignoring node." << std::endl; return NULL; } // Naming the node (group) osgnode->setName( dnodefn.name().asChar() ); return osgnode; }
liqRibCurvesData::liqRibCurvesData( MObject curveGroup ) : nverts(), CVs(), NuCurveWidth() { CM_TRACE_FUNC("liqRibCurvesData::liqRibCurvesData("<<curveGroup.apiTypeStr()<<")"); LIQDEBUGPRINTF( "-> creating nurbs curve group\n" ); MStatus status( MS::kSuccess ); MFnDagNode fnDag( curveGroup, &status ); MFnDagNode fnTrans( fnDag.parent( 0 ) ); MSelectionList groupList; groupList.add( fnTrans.partialPathName() ); MDagPath groupPath; groupList.getDagPath( 0, groupPath ); MMatrix m( groupPath.inclusiveMatrix() ); MStringArray curveList; MObjectArray curveObj; MDagPathArray curveDag; // using the transforms not the nurbsCurves so instances are supported MGlobal::executeCommand( MString( "ls -dag -type transform " ) + fnTrans.partialPathName(), curveList ); for( unsigned i( 0 ); i < curveList.length(); i++ ) { MSelectionList list; list.add( curveList[i] ); MObject curveNode; MDagPath path; list.getDependNode( 0, curveNode ); list.getDagPath( 0, path ); MFnDagNode fnCurve( curveNode ); MObject shape( fnCurve.child( 0 ) ); if( shape.hasFn( MFn::kNurbsCurve ) ) { curveObj.append( curveNode ); curveDag.append( path ); } } if( liqglo.liqglo_renderAllCurves ) ncurves = curveObj.length(); else ncurves = 0; if( !ncurves ) return; nverts = shared_array< RtInt >( new RtInt[ ncurves ] ); unsigned cvcount( 0 ); unsigned long curvePts(0); for( unsigned i( 0 ); i < ncurves; i++ ) { MFnDagNode fnDag( curveObj[i] ); MFnNurbsCurve fnCurve( fnDag.child( 0 ) ); nverts[i] = fnCurve.numCVs() + 4; cvcount += nverts[i]; } CVs = shared_array< RtFloat >( new RtFloat[ cvcount * 3 ] ); unsigned k( 0 ); for( unsigned i( 0 ); i < ncurves; i++ ) { MFnDagNode fnCurve( curveObj[i] ); MMatrix mCurve( curveDag[i].inclusiveMatrix() ); mCurve -= m; mCurve += MMatrix::identity; MObject oCurveChild( fnCurve.child( 0 ) ); MItCurveCV curveIt( oCurveChild ); MPoint pt = curveIt.position(); pt *= mCurve; CVs[k++] = (float)pt.x; CVs[k++] = (float)pt.y; CVs[k++] = (float)pt.z; CVs[k++] = (float)pt.x; CVs[k++] = (float)pt.y; CVs[k++] = (float)pt.z; for( curveIt.reset(); !curveIt.isDone(); curveIt.next() ) { pt = curveIt.position(); pt *= mCurve; CVs[k++] = (float)pt.x; CVs[k++] = (float)pt.y; CVs[k++] = (float)pt.z; } CVs[k++] = (float)pt.x; CVs[k++] = (float)pt.y; CVs[k++] = (float)pt.z; CVs[k++] = (float)pt.x; CVs[k++] = (float)pt.y; CVs[k++] = (float)pt.z; } liqTokenPointer pointsPointerPair; pointsPointerPair.set( "P", rPoint, cvcount ); pointsPointerPair.setDetailType( rVertex ); pointsPointerPair.setTokenFloats( CVs ); // Warning: CVs shares ownership with of its data with pointsPointerPair now! // Saves us from redundant copying as long as we know what we are doing tokenPointerArray.push_back( pointsPointerPair ); // constant width or not float baseWidth( .1 ), tipWidth( .1 ); bool constantWidth( false ); liquidGetPlugValue( fnDag, "liquidCurveBaseWidth", baseWidth, status ); liquidGetPlugValue( fnDag, "liquidCurveTipWidth", tipWidth, status ); if( tipWidth == baseWidth ) constantWidth = true; if ( constantWidth ) { liqTokenPointer pConstWidthPointerPair; pConstWidthPointerPair.set( "constantwidth", rFloat ); pConstWidthPointerPair.setDetailType( rConstant ); pConstWidthPointerPair.setTokenFloat( 0, baseWidth ); tokenPointerArray.push_back( pConstWidthPointerPair ); } else { NuCurveWidth = shared_array< RtFloat >( new RtFloat[ cvcount - ncurves * 2 ] ); k = 0; for( unsigned i( 0 ); i < ncurves; i++ ) { // easy way just linear - might have to be refined MItCurveCV itCurve( curveObj[i] ); NuCurveWidth[k++] = baseWidth; NuCurveWidth[k++] = baseWidth; for( unsigned n( 3 ); n < nverts[i] - 3; n++ ) { float difference = tipWidth - baseWidth; if( difference < 0 ) difference *= -1; float basew ( baseWidth ); if( baseWidth > tipWidth ) NuCurveWidth[k++] = basew - ( n - 2 ) * difference / ( nverts[i] - 5 ); else NuCurveWidth[k++] = basew + ( n - 2 ) * difference / ( nverts[i] - 5 ); } NuCurveWidth[k++] = tipWidth; NuCurveWidth[k++] = tipWidth; } liqTokenPointer widthPointerPair; widthPointerPair.set( "width", rFloat, cvcount - ncurves * 2 ); widthPointerPair.setDetailType( rVarying ); widthPointerPair.setTokenFloats( NuCurveWidth ); tokenPointerArray.push_back( widthPointerPair ); } addAdditionalSurfaceParameters( curveGroup ); }
void AbcWriteJob::setup(double iFrame, MayaTransformWriterPtr iParent, GetMembersMap& gmMap) { MStatus status; // short-circuit if selection flag is on but this node isn't actively // selected if (mArgs.useSelectionList && !mSList.hasItem(mCurDag)) return; MObject ob = mCurDag.node(); // if instanced, add instancing information and skip if (checkInstance(mCurDag, iParent)) return; // skip all intermediate nodes (and their children) if (util::isIntermediate(ob)) { return; } // skip nodes that aren't renderable (and their children) if (mArgs.excludeInvisible && !util::isRenderable(ob)) { return; } // look for riCurves flag for flattening all curve objects to a curve group MFnDependencyNode fnDepNode(ob, &status); MPlug riCurvesPlug = fnDepNode.findPlug("riCurves", &status); bool riCurvesVal = riCurvesPlug.asBool(); bool writeOutAsGroup = false; if (riCurvesVal) { writeOutAsGroup = checkCurveGrp(); if (writeOutAsGroup == false) { MString msg = "Curves have different degrees or close "; msg += "states, not writing out as curve group"; MGlobal::displayWarning(msg); } } if ( status == MS::kSuccess && riCurvesVal && writeOutAsGroup) { MayaNurbsCurveWriterPtr nurbsCurve; if (iParent == NULL) { Alembic::Abc::OObject obj = mRoot.getTop(); nurbsCurve = MayaNurbsCurveWriterPtr(new MayaNurbsCurveWriter( mCurDag, obj, mShapeTimeIndex, true, mArgs)); } else { Alembic::Abc::OObject obj = iParent->getObject(); nurbsCurve = MayaNurbsCurveWriterPtr(new MayaNurbsCurveWriter( mCurDag, obj, mShapeTimeIndex, true, mArgs)); } mCurveList.push_back(nurbsCurve); mStats.mCurveAnimNum++; mStats.mCurveAnimCurves += nurbsCurve->getNumCurves(); mStats.mCurveAnimCVs += nurbsCurve->getNumCVs(); AttributesWriterPtr attrs = nurbsCurve->getAttrs(); if (mShapeTimeIndex != 0 && attrs->isAnimated()) mShapeAttrList.push_back(attrs); } else if (ob.hasFn(MFn::kTransform)) { MFnTransform fnTrans(ob, &status); if (status != MS::kSuccess) { MString msg = "Initialize transform node "; msg += mCurDag.fullPathName(); msg += " failed, skipping."; MGlobal::displayWarning(msg); return; } MayaTransformWriterPtr trans; // parented to the root case if (iParent == NULL) { Alembic::Abc::OObject obj = mRoot.getTop(); trans = MayaTransformWriterPtr(new MayaTransformWriter( obj, mCurDag, mTransTimeIndex, mArgs)); } else { trans = MayaTransformWriterPtr(new MayaTransformWriter( *iParent, mCurDag, mTransTimeIndex, mArgs)); } mTransList.push_back(trans); mStats.mTransAnimNum++; AttributesWriterPtr attrs = trans->getAttrs(); if (mTransTimeIndex != 0 && attrs->isAnimated()) mTransAttrList.push_back(attrs); // loop through the children, making sure to push and pop them // from the MDagPath unsigned int numChild = mCurDag.childCount(); for (unsigned int i = 0; i < numChild; ++i) { if (mCurDag.push(mCurDag.child(i)) == MS::kSuccess) { setup(iFrame, trans, gmMap); mCurDag.pop(); } } } else if (ob.hasFn(MFn::kLocator)) { MFnDependencyNode fnLocator(ob, & status); if (status != MS::kSuccess) { MString msg = "Initialize locator node "; msg += mCurDag.fullPathName(); msg += " failed, skipping."; MGlobal::displayWarning(msg); return; } if (iParent != NULL) { Alembic::Abc::OObject obj = iParent->getObject(); MayaLocatorWriterPtr locator(new MayaLocatorWriter( mCurDag, obj, mShapeTimeIndex, mArgs)); mLocatorList.push_back(locator); mStats.mLocatorAnimNum++; AttributesWriterPtr attrs = locator->getAttrs(); if (mShapeTimeIndex != 0 && attrs->isAnimated()) mShapeAttrList.push_back(attrs); } else { MString err = "Can't translate "; err += fnLocator.name() + " since it doesn't have a parent."; MGlobal::displayError(err); } } else if (ob.hasFn(MFn::kParticle)) { MFnParticleSystem mFnParticle(ob, &status); if (status != MS::kSuccess) { MString msg = "Initialize particle system "; msg += mCurDag.fullPathName(); msg += " failed, skipping."; MGlobal::displayWarning(msg); return; } if (iParent != NULL) { Alembic::Abc::OObject obj = iParent->getObject(); MayaPointPrimitiveWriterPtr particle(new MayaPointPrimitiveWriter( iFrame, mCurDag, obj, mShapeTimeIndex, mArgs)); mPointList.push_back(particle); mStats.mPointAnimNum++; mStats.mPointAnimCVs += particle->getNumCVs(); AttributesWriterPtr attrs = particle->getAttrs(); if (mShapeTimeIndex != 0 && attrs->isAnimated()) mShapeAttrList.push_back(attrs); } else { MString err = "Can't translate "; err += mFnParticle.name() + " since it doesn't have a parent."; MGlobal::displayError(err); } } else if (ob.hasFn(MFn::kMesh)) { MFnMesh fnMesh(ob, &status); if (status != MS::kSuccess) { MString msg = "Initialize mesh node "; msg += mCurDag.fullPathName(); msg += " failed, skipping."; MGlobal::displayWarning(msg); return; } if (iParent != NULL) { Alembic::Abc::OObject obj = iParent->getObject(); MayaMeshWriterPtr mesh(new MayaMeshWriter(mCurDag, obj, mShapeTimeIndex, mArgs, gmMap)); mMeshList.push_back(mesh); if (mesh->isSubD()) { mStats.mSubDAnimNum++; mStats.mSubDAnimCVs += mesh->getNumCVs(); mStats.mSubDAnimFaces += mesh->getNumFaces(); } else { mStats.mPolyAnimNum++; mStats.mPolyAnimCVs += mesh->getNumCVs(); mStats.mPolyAnimFaces += mesh->getNumFaces(); } AttributesWriterPtr attrs = mesh->getAttrs(); if (mShapeTimeIndex != 0 && attrs->isAnimated()) mShapeAttrList.push_back(attrs); } else { MString err = "Can't translate "; err += fnMesh.name() + " since it doesn't have a parent."; MGlobal::displayError(err); } } else if (ob.hasFn(MFn::kCamera)) { MFnCamera fnCamera(ob, &status); if (status != MS::kSuccess) { MString msg = "Initialize camera node "; msg += mCurDag.fullPathName(); msg += " failed, skipping."; MGlobal::displayWarning(msg); return; } if (iParent != NULL) { Alembic::Abc::OObject obj = iParent->getObject(); MayaCameraWriterPtr camera(new MayaCameraWriter( mCurDag, obj, mShapeTimeIndex, mArgs)); mCameraList.push_back(camera); mStats.mCameraAnimNum++; AttributesWriterPtr attrs = camera->getAttrs(); if (mShapeTimeIndex != 0 && attrs->isAnimated()) mShapeAttrList.push_back(attrs); } else { MString err = "Can't translate "; err += fnCamera.name() + " since it doesn't have a parent."; MGlobal::displayError(err); } } else if (ob.hasFn(MFn::kNurbsSurface)) { MFnNurbsSurface fnNurbsSurface(ob, &status); if (status != MS::kSuccess) { MString msg = "Initialize nurbs surface "; msg += mCurDag.fullPathName(); msg += " failed, skipping."; MGlobal::displayWarning(msg); return; } if (iParent != NULL) { Alembic::Abc::OObject obj = iParent->getObject(); MayaNurbsSurfaceWriterPtr nurbsSurface(new MayaNurbsSurfaceWriter( mCurDag, obj, mShapeTimeIndex, mArgs)); mNurbsList.push_back(nurbsSurface); mStats.mNurbsAnimNum++; mStats.mNurbsAnimCVs += nurbsSurface->getNumCVs(); AttributesWriterPtr attrs = nurbsSurface->getAttrs(); if (mShapeTimeIndex != 0 && attrs->isAnimated()) mShapeAttrList.push_back(attrs); } else { MString err = "Can't translate "; err += fnNurbsSurface.name() + " since it doesn't have a parent."; MGlobal::displayError(err); } } else if (ob.hasFn(MFn::kNurbsCurve)) { MFnNurbsCurve fnNurbsCurve(ob, &status); if (status != MS::kSuccess) { MString msg = "Initialize curve node "; msg += mCurDag.fullPathName(); msg += " failed, skipping."; MGlobal::displayWarning(msg); return; } if (iParent != NULL) { Alembic::Abc::OObject obj = iParent->getObject(); MayaNurbsCurveWriterPtr nurbsCurve(new MayaNurbsCurveWriter( mCurDag, obj, mShapeTimeIndex, false, mArgs)); mCurveList.push_back(nurbsCurve); mStats.mCurveAnimNum++; mStats.mCurveAnimCurves++; mStats.mCurveAnimCVs += nurbsCurve->getNumCVs(); AttributesWriterPtr attrs = nurbsCurve->getAttrs(); if (mShapeTimeIndex != 0 && attrs->isAnimated()) mShapeAttrList.push_back(attrs); } else { MString err = "Can't translate "; err += fnNurbsCurve.name() + " since it doesn't have a parent."; MGlobal::displayError(err); } } else { MString warn = mCurDag.fullPathName() + " is an unsupported type of "; warn += ob.apiTypeStr(); MGlobal::displayWarning(warn); } }
MStatus exportF3d::doIt(const MArgList& args) { MStatus status; MString result; status = parseArgs(args); if (!status) { status.perror("Parsing error"); return status; } float currentFrame = MAnimControl::currentTime().value(); MItSelectionList selListIter(m_slist, MFn::kFluid, &status); for (; !selListIter.isDone(); selListIter.next()) { MDagPath dagPath; MObject selectedObject; status = selListIter.getDependNode(selectedObject); status = selListIter.getDagPath(dagPath); // Create function set for the fluid MFnFluid fluidFn(dagPath, &status); if (status != MS::kSuccess) continue; if (m_verbose) { cout << "------------------------------------------------------" << endl; cout << " Selected object: " << fluidFn.name() << endl; cout << " Selected object type: " << selectedObject.apiTypeStr() << endl; cout << endl << endl; } MFnFluid::FluidMethod method; MFnFluid::FluidGradient gradient; status = fluidFn.getDensityMode(method, gradient); if(method != MFnFluid::kStaticGrid && method != MFnFluid::kDynamicGrid) { m_density = false; } status = fluidFn.getTemperatureMode(method, gradient); if(method != MFnFluid::kStaticGrid && method != MFnFluid::kDynamicGrid) { m_temperature = false; } status = fluidFn.getFuelMode(method, gradient); if(method != MFnFluid::kStaticGrid && method != MFnFluid::kDynamicGrid) { m_fuel = false; } status = fluidFn.getVelocityMode(method, gradient); if(method != MFnFluid::kStaticGrid && method != MFnFluid::kDynamicGrid) { m_vel = false; } if (m_color) { MFnFluid::ColorMethod colorMethod; fluidFn.getColorMode(colorMethod); if(colorMethod == MFnFluid::kUseShadingColor) { m_color = false; } } if (!m_vel) { // Note that the pressure data only exists if the velocity method // is kStaticGrid or kDynamicGrid m_pressure = false; } if (m_falloff) { MFnFluid::FalloffMethod falloffMethod; status = fluidFn.getFalloffMode(falloffMethod); if(falloffMethod != MFnFluid::kNoFalloffGrid ) { m_falloff = false; } } // Go through the selected frame range MComputation computation; computation.beginComputation(); char fluidPath[1024]; for(int frame=m_start ; frame <= m_end; ++frame) { int numOversample = m_numOversample; if (frame == m_start) numOversample = 1; float dt = 1.0/double(numOversample); for ( int s=numOversample-1 ; s >= 0 ; --s) { if (computation.isInterruptRequested()) break ; float time = frame - s*dt; status = MAnimControl::setCurrentTime(time); //MPlug plugGrid = fluidFn.findPlug( "outGrid",true,&status); MGlobal::displayInfo(MString("Setting Current frame ")+time); } sprintf(fluidPath, "%s/%s.%04d.f3d", m_outputPath.asChar(), fluidFn.name().asChar(),frame); MGlobal::displayInfo(MString("Writting: ")+fluidPath); setF3dField(fluidFn, fluidPath, dagPath); } computation.endComputation(); // only one fluid object break; } setResult(result); MAnimControl::setCurrentTime(currentFrame); return MS::kSuccess; }