//-*****************************************************************************
M44d getFinalMatrix( IObject &iObj )
{
    M44d xf;
    xf.makeIdentity();

    IObject parent = iObj.getParent();

    while ( parent )
    {
        accumXform( xf, parent );
        parent = parent.getParent();
    }

    return xf;
}
Ejemplo n.º 2
0
/// Guess position in 3D corresponding to a 2D click
///
/// `clickPos` - 2D position in viewport, as from a mouse event.
Imath::V3d View3D::guessClickPosition(const QPoint& clickPos)
{
    // Get new point in the projected coordinate system using the click
    // position x,y and the z of a reference position.  Take the reference point
    // of interest to be between the camera rotation center and the camera
    // position, as a rough guess of the depth the user is interested in.
    //
    // This works pretty well, except when there are noise points intervening
    // between the reference position and the user's actual point of interest.
    V3d refPos = 0.3*m_camera.position() + 0.7*m_camera.center();
    M44d mat = m_camera.viewMatrix()*m_camera.projectionMatrix()*m_camera.viewportMatrix();
    double refZ = (refPos * mat).z;
    V3d newPointProj(clickPos.x(), clickPos.y(), refZ);
    // Map projected point back into model coordinates
    return newPointProj * mat.inverse();
}
Ejemplo n.º 3
0
void ofxAlembic::IXform::updateWithTimeInternal(double time, Imath::M44f& transform)
{
	ISampleSelector ss(time, ISampleSelector::kNearIndex);

	M44f mat;
	M44d m = m_xform.getSchema().getValue(ss).getMatrix();
	double *src = m.getValue();
	float *dst = mat.getValue();

	for (int i = 0; i < 16; i++)
		dst[i] = src[i];

	transform = mat * transform;
	
	for (int i = 0; i < 16; i++)
	{
		xform.local_matrix.getPtr()[i] = mat.getValue()[i];
		xform.global_matrix.getPtr()[i] = transform.getValue()[i];
	}
}
Ejemplo n.º 4
0
void MatrixFieldMapping::updateTransform() 
{
  typedef MatrixCurve::SampleVec::const_iterator SampleIter;

  // Build the voxel to world space transforms ---
  M44d lsToVs;
  getLocalToVoxelMatrix(lsToVs);
  M44d vsToLs = lsToVs.inverse();
  // Loop over all samples in lsToWs, append vsToLs and create new curve
  // Also handle the special case where lsToWs has no samples. In that
  // case m_vsToWsCurve still has to have one sample.
  const MatrixCurve::SampleVec &lsToWs = m_lsToWsCurve.samples();
  m_vsToWsCurve.clear();
  for (SampleIter i = lsToWs.begin(), end = lsToWs.end(); i != end; i++) {
    m_vsToWsCurve.addSample(i->first, vsToLs * i->second);
  }

  // See if the curve has more than just a single sample
  m_isTimeVarying = m_lsToWsCurve.numSamples() > 1;

  // Sample the time-varying transforms at time=0.0
  m_lsToWs = m_lsToWsCurve.linear(0.0);
  m_wsToLs = m_lsToWs.inverse();
  m_vsToWs = vsToLs * m_lsToWs;
  m_wsToVs = m_vsToWs.inverse();

  // Precompute the voxel size
  V3d voxelOrigin, nextVoxel;
  m_vsToWs.multVecMatrix(V3d(0, 0, 0), voxelOrigin);
  m_vsToWs.multVecMatrix(V3d(1, 0, 0), nextVoxel);
  m_wsVoxelSize.x = (nextVoxel - voxelOrigin).length();
  m_vsToWs.multVecMatrix(V3d(0, 1, 0), nextVoxel);
  m_wsVoxelSize.y = (nextVoxel - voxelOrigin).length();
  m_vsToWs.multVecMatrix(V3d(0, 0, 1), nextVoxel);
  m_wsVoxelSize.z = (nextVoxel - voxelOrigin).length();
}
Ejemplo n.º 5
0
void FrustumFieldMapping::setTransforms(float t, 
                                        const M44d &ssToWs, const M44d &csToWs)
{
  if (m_defaultState) {
    clearCurves();
    m_defaultState = false;
  }

  // Construct local-to-world transform from ssToWs
  M44d lsToSs, scale, translation;
  scale.setScale(V3d(2.0, 2.0, 1.0));
  translation.setTranslation(V3d(-1.0, -1.0, 0.0));
  lsToSs = scale * translation;
  M44d lpsToWs = lsToSs * ssToWs;

  // Add samples to Curves
  m_ssToWsCurve.addSample(t, ssToWs);
  m_lpsToWsCurve.addSample(t, lpsToWs);
  m_csToWsCurve.addSample(t, csToWs);

  // Compute near and far planes ---

  // Because the frustum may be skewed we can't just measure distance from
  // the apex of the frustum to the world-space center point of the frustum.
  // Instead, we transform into camera space and measure z depth there.

  V3d lsNearP(0.5, 0.5, 0.0), lsFarP(0.5, 0.5, 1.0);
  V3d wsNearP, wsFarP, csNearP, csFarP;

  lpsToWs.multVecMatrix(lsNearP, wsNearP);
  lpsToWs.multVecMatrix(lsFarP, wsFarP);

  M44d wsToCs = csToWs.inverse();
  wsToCs.multVecMatrix(wsNearP, csNearP);
  wsToCs.multVecMatrix(wsFarP, csFarP);

  double near = -csNearP.z;
  double far = -csFarP.z;

  // Catch NaN here
  if (isnan(near) || isnan(far)) {
    throw BadPerspectiveMatrix("FrustumFieldMapping::setTransforms "
                               "received bad screen-to-world matrix");
  }

  m_nearCurve.addSample(t, near);
  m_farCurve.addSample(t, far);

  computeVoxelSize();
}
Ejemplo n.º 6
0
void FrustumFieldMapping::reset()
{
  // Default camera to world ---

  M44d csToWs;
  csToWs.makeIdentity();

  // Default screen to world ---

  double near = 1;
  double far = 2;
  double fovRadians = 45.0 * M_PI / 180.0;
  double invTan = 1.0 / std::tan(fovRadians / 2.0);
  double imageAspectRatio = 1.0;

  M44d perspective(1, 0, 0, 0,
                   0, 1, 0, 0,
                   0, 0, (far) / (far - near),          1,
                   0, 0, (- far * near) / (far - near), 0);

  M44d fov;
  fov.setScale(V3d(invTan / imageAspectRatio, invTan, 1.0));
  
  M44d flipZ;
  flipZ.setScale(V3d(1.0, 1.0, -1.0));
  
  M44d csToSs = flipZ * perspective * fov;

  M44d standardSsToWs = csToSs.inverse() * csToWs;

  // Set default state ---

  clearCurves();
  setTransforms(standardSsToWs, csToWs);

  m_defaultState = true;

  computeVoxelSize();
}
//-*****************************************************************************
void xformOut()
{
    OArchive archive( Alembic::AbcCoreOgawa::WriteArchive(), "Xform1.abc" );

    OXform a( OObject( archive, kTop ), "a" );
    OXform b( a, "b" );
    OXform c( b, "c" );
    OXform d( c, "d" );
    OXform e( d, "e" );
    OXform f( e, "f" );
    OXform g( f, "g" );

    XformOp transop( kTranslateOperation, kTranslateHint );
    XformOp scaleop( kScaleOperation, kScaleHint );
    XformOp matrixop( kMatrixOperation, kMatrixHint );

    TESTING_ASSERT( a.getSchema().getNumSamples() == 0 );

    OBox3dProperty childBounds = a.getSchema().getChildBoundsProperty();

    XformSample asamp;
    for ( size_t i = 0; i < 20; ++i )
    {
        asamp.addOp( transop, V3d( 12.0, i + 42.0, 20.0 ) );

        if ( i >= 18 )
        {
            childBounds.set( Abc::Box3d( V3d( -1.0, -1.0, -1.0 ),
                                         V3d( 1.0, 1.0, 1.0 ) ) );
        }
        else
        {
            childBounds.set( Abc::Box3d() );
        }

        a.getSchema().set( asamp );
    }

    XformSample bsamp;
    for ( size_t i = 0 ; i < 20 ; ++i )
    {
        bsamp.setInheritsXforms( (bool)(i&1) );

        b.getSchema().set( bsamp );
    }

    // for c we write nothing

    XformSample dsamp;
    dsamp.addOp( scaleop, V3d( 3.0, 6.0, 9.0 ) );
    d.getSchema().set( dsamp );

    XformSample esamp;
    M44d identmat;
    identmat.makeIdentity();

    esamp.addOp( transop, V3d( 0.0, 0.0, 0.0 ) );
    esamp.addOp( XformOp( kMatrixOperation, kMatrixHint ), identmat );
    esamp.addOp( scaleop, V3d( 1.0, 1.0, 1.0 ) );
    e.getSchema().set( esamp );

    XformSample fsamp;
    fsamp.addOp( transop, V3d( 3.0, -4.0, 5.0 ) );
    f.getSchema().set( fsamp );

    // this will cause the Xform's values property to be an ArrayProperty,
    // since there will be 20 * 16 channels.
    XformSample gsamp;
    Abc::M44d gmatrix;
    gmatrix.makeIdentity();
    for ( size_t i = 0 ; i < 20 ; ++i )
    {
        gmatrix.x[0][1] = (double)i;
        gsamp.addOp( matrixop, gmatrix );
    }
    g.getSchema().set( gsamp );
}
//-*****************************************************************************
void someOpsXform()
{
    std::string name = "someOpsXform.abc";
    {
        OArchive archive( Alembic::AbcCoreOgawa::WriteArchive(), name );

        OXform a( OObject( archive, kTop ), "a" );

        OBox3dProperty bnds = CreateOArchiveBounds( archive );

        XformOp transop( kTranslateOperation, kTranslateHint );
        XformOp scaleop( kScaleOperation, kScaleHint );

        XformSample asamp;

        // scale
        asamp.addOp( scaleop, V3d( 2.0, 1.0, 2.0 ) );

        // Maya-like shear
        XformOp shearmatrixop( kMatrixOperation, kMayaShearHint );
        M44d shearmat;
        shearmat.makeIdentity();

        asamp.addOp( shearmatrixop, shearmat );

        // rotate x axis
        XformOp rotop( kRotateOperation, kRotateHint );
        asamp.addOp( rotop, V3d( 1.0, 0.0, 0.0 ), 1.57 );

        // rotate y axis, angle will be animated
        asamp.addOp( rotop, V3d( 0.0, 1.0, 0.0 ), 0.125 );

        // rotate z axis, use a different hint for fun
        XformOp rotorientop( kRotateOperation, kRotateOrientationHint );
        asamp.addOp( rotorientop, V3d( 0.0, 0.0, 1.0 ), 0.1 );

        // translate with animated y and z, different hint for fun
        XformOp transpivotop( kTranslateOperation, kRotatePivotPointHint );
        asamp.addOp( transpivotop, V3d( 0.0, 0.0, 0.0 ) );

        a.getSchema().set( asamp );
        bnds.set( Box3d( V3d( -0.1, -0.1, -0.1 ),
                         V3d(  0.1,  0.1,  0.1 ) ) );

        for (size_t i = 1; i < 5 ; ++i)
        {
            asamp.addOp( scaleop, V3d( 2 * ( i + 1 ),
                                       1.0, 2.0 ) );

            shearmat.x[1][0] = (double)i;
            shearmat.x[2][0] = (double)( (int)i * -1.0 );
            shearmat.x[2][1] = 0.0;

            asamp.addOp( shearmatrixop, shearmat );

            asamp.addOp( rotop, V3d( 1.0, 0.0, 0.0 ),
                         1.57 );
            asamp.addOp( rotop, V3d( 0.0, 1.0, 0.0 ),
                         0.125 * ( i + 1 ) );
            asamp.addOp( rotorientop, V3d( 0.0, 0.0, 1.0 ),
                         0.1 * ( i + 1 ) );

            asamp.addOp( transpivotop, V3d( 0.0, 3.0 * i, 4.0 * i ) );

            a.getSchema().set( asamp );
            double iVal = static_cast< double >( i );
            bnds.set( Box3d( V3d( -iVal, -iVal, -iVal ),
                             V3d(  iVal,  iVal,  iVal ) ) );
        }

    }

    {
        IArchive archive( Alembic::AbcCoreOgawa::ReadArchive(), name );

        IXform a( IObject( archive, kTop ), "a" );
        IBox3dProperty bnds = GetIArchiveBounds( archive );

        XformSample asamp;

        a.getSchema().get( asamp );

        TESTING_ASSERT( a.getSchema().getNumOps() == 6 );

        TESTING_ASSERT( asamp[0].isScaleOp() );
        TESTING_ASSERT( asamp[0].getHint() == kScaleHint );

        TESTING_ASSERT( asamp[1].isMatrixOp() );
        TESTING_ASSERT( asamp[1].getHint() == kMayaShearHint );

        TESTING_ASSERT( asamp[2].isRotateOp() );
        TESTING_ASSERT( asamp[2].getHint() == kRotateHint );

        TESTING_ASSERT( asamp[3].getType() == kRotateOperation );
        TESTING_ASSERT( asamp[3].getHint() == kRotateHint );

        TESTING_ASSERT( asamp[4].getType() == kRotateOperation );
        TESTING_ASSERT( asamp[4].getHint() == kRotateOrientationHint );

        TESTING_ASSERT( asamp[5].getType() == kTranslateOperation );
        TESTING_ASSERT( asamp[5].getHint() == kRotatePivotPointHint );

        TESTING_ASSERT( asamp[0].isXAnimated() );
        TESTING_ASSERT( !asamp[0].isYAnimated() );
        TESTING_ASSERT( !asamp[0].isZAnimated() );

        TESTING_ASSERT( !asamp[1].isChannelAnimated(0) );  // [0][0]
        TESTING_ASSERT( !asamp[1].isChannelAnimated(1) );  // [0][1]
        TESTING_ASSERT( !asamp[1].isChannelAnimated(2) );  // [0][2]
        TESTING_ASSERT( !asamp[1].isChannelAnimated(3) );  // [0][3]
        TESTING_ASSERT( asamp[1].isChannelAnimated(4) );   // [1][0]
        TESTING_ASSERT( !asamp[1].isChannelAnimated(5) );  // [1][1]
        TESTING_ASSERT( !asamp[1].isChannelAnimated(6) );  // [1][2]
        TESTING_ASSERT( !asamp[1].isChannelAnimated(7) );  // [1][3]
        TESTING_ASSERT( asamp[1].isChannelAnimated(8) );   // [2][0]
        TESTING_ASSERT( !asamp[1].isChannelAnimated(9) );  // [2][1]
        TESTING_ASSERT( !asamp[1].isChannelAnimated(10) ); // [2][2]
        TESTING_ASSERT( !asamp[1].isChannelAnimated(11) ); // [2][3]
        TESTING_ASSERT( !asamp[1].isChannelAnimated(12) ); // [3][0]
        TESTING_ASSERT( !asamp[1].isChannelAnimated(13) ); // [3][1]
        TESTING_ASSERT( !asamp[1].isChannelAnimated(14) ); // [3][2]
        TESTING_ASSERT( !asamp[1].isChannelAnimated(15) ); // [3][3]

        TESTING_ASSERT( !asamp[2].isXAnimated() );
        TESTING_ASSERT( !asamp[2].isYAnimated() );
        TESTING_ASSERT( !asamp[2].isZAnimated() );
        TESTING_ASSERT( !asamp[2].isAngleAnimated() );

        TESTING_ASSERT( !asamp[3].isXAnimated() );
        TESTING_ASSERT( !asamp[3].isYAnimated() );
        TESTING_ASSERT( !asamp[3].isZAnimated() );
        TESTING_ASSERT( asamp[3].isAngleAnimated() );

        TESTING_ASSERT( !asamp[4].isXAnimated() );
        TESTING_ASSERT( !asamp[4].isYAnimated() );
        TESTING_ASSERT( !asamp[4].isZAnimated() );
        TESTING_ASSERT( asamp[4].isAngleAnimated() );

        TESTING_ASSERT( !asamp[5].isXAnimated() );
        TESTING_ASSERT( asamp[5].isYAnimated() );
        TESTING_ASSERT( asamp[5].isZAnimated() );

        // OK, now check the values came through
        M44d shearmat;
        shearmat.makeIdentity();

        TESTING_ASSERT( asamp[0].getScale() == V3d( 2.0, 1.0, 2.0 ) );

        TESTING_ASSERT( asamp[1].getMatrix() == shearmat );

        TESTING_ASSERT( asamp[2].getAxis() == V3d( 1.0, 0.0, 0.0 ) );
        TESTING_ASSERT( almostEqual( asamp[2].getAngle(), 1.57 ) );

        TESTING_ASSERT( asamp[3].getAxis() == V3d( 0.0, 1.0, 0.0 ) );
        TESTING_ASSERT( almostEqual( asamp[3].getAngle(), 0.125 ) );

        TESTING_ASSERT( asamp[4].getAxis() == V3d( 0.0, 0.0, 1.0 ) );
        TESTING_ASSERT( almostEqual( asamp[4].getAngle(), 0.1 ) );

        TESTING_ASSERT( asamp[5].getTranslate() == V3d( 0.0, 0.0, 0.0 ) );

        TESTING_ASSERT( bnds.getValue() == Box3d( V3d( -0.1, -0.1, -0.1 ),
                                                  V3d(  0.1,  0.1,  0.1 ) ) );

        for ( index_t i = 1; i < 5 ; ++i )
        {
            a.getSchema().get( asamp, ISampleSelector( i ) );

            TESTING_ASSERT( asamp[0].getScale()
                            == V3d( 2 * ( i + 1 ), 1.0, 2.0 ) );

            shearmat.x[1][0] = (double)i;
            shearmat.x[2][0] = (double)( (int)i * -1.0 );
            shearmat.x[2][1] = 0.0;

            TESTING_ASSERT( asamp[1].getMatrix() == shearmat );

            TESTING_ASSERT( asamp[2].getAxis() == V3d( 1.0, 0.0, 0.0 ) );
            TESTING_ASSERT( almostEqual( asamp[2].getAngle(), 1.57 ) );

            TESTING_ASSERT( asamp[3].getAxis() == V3d( 0.0, 1.0, 0.0 ) );
            TESTING_ASSERT( almostEqual( asamp[3].getAngle(),
                                         0.125 * ( i + 1 ) ) );

            TESTING_ASSERT( asamp[4].getAxis() == V3d( 0.0, 0.0, 1.0 ) );
            TESTING_ASSERT( almostEqual( asamp[4].getAngle(),
                                         0.1 * ( i + 1 ) ) );

            V3d tvec( 0.0, 3.0 * i, 4.0 * i );

            TESTING_ASSERT( tvec.equalWithAbsError( asamp[5].getTranslate(),
                                                    VAL_EPSILON ) );
            Box3d b = bnds.getValue( ISampleSelector( i ) );
            double iVal = static_cast< double >( i );
            TESTING_ASSERT( b == Box3d( V3d( -iVal, -iVal, -iVal ),
                                        V3d(  iVal,  iVal,  iVal ) ) );
        }

        std::cout << "tested all xforms in " << name << std::endl;
    }
}
Ejemplo n.º 9
0
void exportF3d::setF3dField(MFnFluid &fluidFn, const char *outputPath, 
                            const MDagPath &dagPath)
{
    
  try { 
      
    MStatus stat;

    unsigned int i, xres = 0, yres = 0, zres = 0;
    double xdim,ydim,zdim;
    // Get the resolution of the fluid container      
    stat = fluidFn.getResolution(xres, yres, zres);
    stat = fluidFn.getDimensions(xdim, ydim, zdim);
    V3d size(xdim,ydim,zdim);
    const V3i res(xres, yres, zres);
    int psizeTot  = fluidFn.gridSize();

    /// get the transform and rotation
    MObject parentObj = fluidFn.parent(0, &stat);
    if (stat != MS::kSuccess) {

      MGlobal::displayError("Can't find fluid's parent node");
      return;
    }
    MDagPath parentPath = dagPath;
    parentPath.pop();
    MTransformationMatrix tmatFn(dagPath.inclusiveMatrix());
    if (stat != MS::kSuccess) {

      MGlobal::displayError("Failed to get transformation matrix of fluid's parent node");
      return;
    }


    MFnTransform fnXform(parentPath, &stat);
    if (stat != MS::kSuccess) {

      MGlobal::displayError("Can't create a MFnTransform from fluid's parent node");
      return;
    }
          

    if (m_verbose)
    {
      fprintf(stderr, "cellnum: %dx%dx%d = %d\n",  
              xres, yres, zres,psizeTot);
    }

    float *density(NULL), *temp(NULL), *fuel(NULL);
    float *pressure(NULL), *falloff(NULL);
      
    density = fluidFn.density( &stat );
    if ( stat.error() ) m_density = false;

    temp    = fluidFn.temperature( &stat );
    if ( stat.error() ) m_temperature = false;
      
    fuel    = fluidFn.fuel( &stat );
    if ( stat.error() ) m_fuel = false;    
      
    pressure= fluidFn.pressure( &stat );
    if ( stat.error() ) m_pressure = false;

    falloff = fluidFn.falloff( &stat );
    if ( stat.error() ) m_falloff = false;

    float *r,*g,*b;
    if (m_color) {
      stat = fluidFn.getColors(r,b,g);
      if ( stat.error() ) m_color = false;
    }else
      m_color = false;
      
    float *u,*v,*w;
    if (m_texture) {
      stat = fluidFn.getCoordinates(u,v,w);
      if ( stat.error() ) m_texture = false;
    }else
      m_texture = false;

    /// velocity info
    float *Xvel(NULL),*Yvel(NULL), *Zvel(NULL);  
    if (m_vel) { 
      stat = fluidFn.getVelocity( Xvel,Yvel,Zvel );
      if ( stat.error() ) m_vel = false;
    }
    

    if (m_density == false && m_temperature==false && m_fuel==false &&
        m_pressure==false && m_falloff==false && m_vel == false && 
        m_color == false && m_texture==false)
    {
      MGlobal::displayError("No fluid attributes found for writing, please check fluids settings");
      return;
    }
            
    /// Fields 
    DenseFieldf::Ptr densityFld, tempFld, fuelFld, pressureFld, falloffFld;
    DenseField3f::Ptr CdFld, uvwFld;
    MACField3f::Ptr vMac;

    MPlug autoResizePlug = fluidFn.findPlug("autoResize", &stat); 
    bool autoResize;
    autoResizePlug.getValue(autoResize);

    // maya's fluid transformation
    V3d dynamicOffset(0);
    M44d localToWorld;
    MatrixFieldMapping::Ptr mapping(new MatrixFieldMapping());

    M44d fluid_mat(tmatFn.asMatrix().matrix);

    if(autoResize) {      
      fluidFn.findPlug("dofx").getValue(dynamicOffset[0]);
      fluidFn.findPlug("dofy").getValue(dynamicOffset[1]);
      fluidFn.findPlug("dofz").getValue(dynamicOffset[2]);
    }

    Box3i extents;
    extents.max = res - V3i(1);
    extents.min = V3i(0);
    mapping->setExtents(extents);
  
    localToWorld.setScale(size);
    localToWorld *= M44d().setTranslation( -(size*0.5) );
    localToWorld *= M44d().setTranslation( dynamicOffset );
    localToWorld *= fluid_mat;
    
    mapping->setLocalToWorld(localToWorld);  
      
    if (m_density){
      densityFld = new DenseFieldf;
      densityFld->setSize(res);
      densityFld->setMapping(mapping);
    }
    if (m_fuel){
      fuelFld = new DenseFieldf;
      fuelFld->setSize(res); 
      fuelFld->setMapping(mapping);
    }
    if (m_temperature){
      tempFld = new DenseFieldf;
      tempFld->setSize(res);
      tempFld->setMapping(mapping);
    }
    if (m_pressure){
      pressureFld = new DenseFieldf;
      pressureFld->setSize(res);
      pressureFld->setMapping(mapping);
    }
    if (m_falloff){
      falloffFld = new DenseFieldf;
      falloffFld->setSize(res);
      falloffFld->setMapping(mapping);
    }
    if (m_vel){
      vMac = new MACField3f;
      vMac->setSize(res);
      vMac->setMapping(mapping);
    } 
    if (m_color){
      CdFld = new DenseField3f;
      CdFld->setSize(res);
      CdFld->setMapping(mapping);
    } 
    if (m_texture){
      uvwFld = new DenseField3f;
      uvwFld->setSize(res);
      uvwFld->setMapping(mapping);
    } 
        
    size_t iX, iY, iZ;      
    for( iZ = 0; iZ < zres; iZ++ ) 
    {
      for( iX = 0; iX < xres; iX++ )
      {
        for( iY = 0; iY < yres ; iY++ ) 
        {
    
          /// data is in x major but we are writting in z major order
          i = fluidFn.index( iX, iY,  iZ);
            
          if ( m_density ) 
            densityFld->lvalue(iX, iY, iZ) = density[i];            
          if ( m_temperature ) 
            tempFld->lvalue(iX, iY, iZ) = temp[i];
          if ( m_fuel )   
            fuelFld->lvalue(iX, iY, iZ) = fuel[i];
          if ( m_pressure )   
            pressureFld->lvalue(iX, iY, iZ) = pressure[i];
          if ( m_falloff )   
            falloffFld->lvalue(iX, iY, iZ) = falloff[i];
          if (m_color)
            CdFld->lvalue(iX, iY, iZ) = V3f(r[i], g[i], b[i]);
          if (m_texture)
            uvwFld->lvalue(iX, iY, iZ) = V3f(u[i], v[i], w[i]);
        }
      }      
    }

      
    if (m_vel) {
      unsigned x,y,z;
      for(z=0;z<zres;++z) for(y=0;y<yres;++y) for(x=0;x<xres+1;++x) {
            vMac->u(x,y,z) = *Xvel++;
          }
        
      for(z=0;z<zres;++z) for(y=0;y<yres+1;++y) for(x=0;x<xres;++x) {
            vMac->v(x,y,z) = *Yvel++;
          }
        
      for(z=0;z<zres+1;++z) for(y=0;y<yres;++y) for(x=0;x<xres;++x) {
            vMac->w(x,y,z) = *Zvel++;
          }                        
    } 
     
    Field3DOutputFile out;
    if (!out.create(outputPath)) {
      MGlobal::displayError("Couldn't create file: "+ MString(outputPath));
      return;
    }

    string fieldname("maya");

    if (m_density){
        out.writeScalarLayer<float>(fieldname, "density", densityFld);
    }
    if (m_fuel) { 
        out.writeScalarLayer<float>(fieldname,"fuel", fuelFld);
    }
    if (m_temperature){
        out.writeScalarLayer<float>(fieldname,"temperature", tempFld);
    }
    if (m_color) {
        out.writeVectorLayer<float>(fieldname,"Cd", CdFld);
    }
    if (m_vel)
      out.writeVectorLayer<float>(fieldname,"v_mac", vMac);      

    out.close(); 

  }
  catch(const std::exception &e)
  {

    MGlobal::displayError( MString(e.what()) );
    return;
  }


}