MObject createNurbs(double iFrame, Alembic::AbcGeom::INuPatch & iNode,
    MObject & iParent)
{
    // normally we'd only want to do the read if we had only 1 sample, but
    // since we can't seem to create an empty Nurbs surface like we can a mesh
    // we will read the data (eventually multiple times on creation)
    MObject obj = readNurbs(iFrame, iNode, iParent);

    if (!obj.isNull())
    {
        MFnNurbsSurface fn(obj);
        setInitialShadingGroup(fn.partialPathName());
    }

    return obj;
}
Exemplo n.º 2
0
MStatus AlembicNode::compute(const MPlug & plug, MDataBlock & dataBlock)
{
    MStatus status;

    // update the frame number to be imported
    MDataHandle speedHandle = dataBlock.inputValue(mSpeedAttr, &status);
    double speed = speedHandle.asDouble();

    MDataHandle offsetHandle = dataBlock.inputValue(mOffsetAttr, &status);
    double offset = offsetHandle.asDouble();

    MDataHandle timeHandle = dataBlock.inputValue(mTimeAttr, &status);
    MTime t = timeHandle.asTime();
    double inputTime = t.as(MTime::kSeconds);

    double fps = getFPS();

    // scale and offset inputTime.
    inputTime = computeAdjustedTime(inputTime, speed, offset/fps);

    // this should be done only once per file
    if (mFileInitialized == false)
    {
        mFileInitialized = true;

        MDataHandle dataHandle = dataBlock.inputValue(mAbcFileNameAttr);
        MFileObject fileObject;
        fileObject.setRawFullName(dataHandle.asString());
        MString fileName = fileObject.resolvedFullName();

        // TODO, make sure the file name, or list of files create a valid
        // Alembic IArchive

        // initialize some flags for plug update
        mSubDInitialized = false;
        mPolyInitialized = false;

        // When an alembic cache will be imported at the first time using
        // AbcImport, we need to set mIncludeFilterAttr (filterHandle) to be
        // mIncludeFilterString for later use. When we save a maya scene(.ma)
        // mIncludeFilterAttr will be saved. Then when we load the saved
        // .ma file, mIncludeFilterString will be set to be mIncludeFilterAttr.
        MDataHandle includeFilterHandle =
                        dataBlock.inputValue(mIncludeFilterAttr, &status);
        MString& includeFilterString = includeFilterHandle.asString();

       if (mIncludeFilterString.length() > 0)
        {
            includeFilterHandle.set(mIncludeFilterString);
            dataBlock.setClean(mIncludeFilterAttr);
        }
        else if (includeFilterString.length() > 0)
        {
            mIncludeFilterString = includeFilterString;
        }

        MDataHandle excludeFilterHandle =
                        dataBlock.inputValue(mExcludeFilterAttr, &status);
        MString& excludeFilterString = excludeFilterHandle.asString();

       if (mExcludeFilterString.length() > 0)
        {
            excludeFilterHandle.set(mExcludeFilterString);
            dataBlock.setClean(mExcludeFilterAttr);
        }
        else if (excludeFilterString.length() > 0)
        {
            mExcludeFilterString = excludeFilterString;
        }


        MFnDependencyNode dep(thisMObject());
        MPlug allSetsPlug = dep.findPlug("allColorSets");
        CreateSceneVisitor visitor(inputTime, !allSetsPlug.isNull(),
            MObject::kNullObj, CreateSceneVisitor::NONE, "",
            mIncludeFilterString, mExcludeFilterString);

        {
           mData.getFrameRange(mSequenceStartTime, mSequenceEndTime);
            MDataHandle startFrameHandle = dataBlock.inputValue(mStartFrameAttr,
                                                                &status);
            startFrameHandle.set(mSequenceStartTime*fps);
            MDataHandle endFrameHandle = dataBlock.inputValue(mEndFrameAttr,
                                                                &status);
            endFrameHandle.set(mSequenceEndTime*fps);
        }
    }

    // Retime
    MDataHandle cycleHandle = dataBlock.inputValue(mCycleTypeAttr, &status);
    short playType = cycleHandle.asShort();
    inputTime = computeRetime(inputTime, mSequenceStartTime, mSequenceEndTime,
                              playType);

    clamp<double>(mSequenceStartTime, mSequenceEndTime, inputTime);

    // update only when the time lapse is big enough
    if (fabs(inputTime - mCurTime) > 0.00001)
    {
        mOutRead = std::vector<bool>(mOutRead.size(), false);
        mCurTime = inputTime;
    }

    if (plug == mOutPropArrayAttr)
    {

        if (mOutRead[0])
        {
            dataBlock.setClean(plug);
            return MS::kSuccess;
        }

        mOutRead[0] = true;

        unsigned int propSize =
            static_cast<unsigned int>(mData.mPropList.size());

        if (propSize > 0)
        {
            MArrayDataHandle outArrayHandle = dataBlock.outputValue(
                mOutPropArrayAttr, &status);

            unsigned int outHandleIndex = 0;
            MDataHandle outHandle;

            // for all of the nodes with sampled attributes
            for (unsigned int i = 0; i < propSize; i++)
            {
                // only use the handle if it matches the index.
                // The index wont line up in the sparse case so we
                // can just skip that element.
                if (outArrayHandle.elementIndex() == outHandleIndex++)
                {
                    outHandle = outArrayHandle.outputValue();
                }
                else
                {
                    continue;
                }

                if (mData.mPropList[i].mArray.valid())
                {
                    readProp(mCurTime, mData.mPropList[i].mArray, outHandle);
                }
                else if (mData.mPropList[i].mScalar.valid())
                {
                    // for visibility only
                    if (mData.mPropList[i].mScalar.getName() ==
                        Alembic::AbcGeom::kVisibilityPropertyName)
                    {
                        Alembic::Util::int8_t visVal = 1;
                        mData.mPropList[i].mScalar.get(&visVal,
                            Alembic::Abc::ISampleSelector(mCurTime,
                                Alembic::Abc::ISampleSelector::kNearIndex ));
                        outHandle.setGenericBool(visVal != 0, false);
                    }
                    else
                    {
                        // for all scalar props
                        readProp(mCurTime, mData.mPropList[i].mScalar, outHandle);
                    }
                }
                outArrayHandle.next();
            }
            outArrayHandle.setAllClean();
        }

    }
    else if (plug == mOutTransOpArrayAttr )
    {
        if (mOutRead[1])
        {
            dataBlock.setClean(plug);
            return MS::kSuccess;
        }

        mOutRead[1] = true;

        unsigned int xformSize =
            static_cast<unsigned int>(mData.mXformList.size());

        if (xformSize > 0)
        {
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutTransOpArrayAttr, &status);

            MPlug arrayPlug(thisMObject(), mOutTransOpArrayAttr);

            MDataHandle outHandle;
            unsigned int outHandleIndex = 0;

            for (unsigned int i = 0; i < xformSize; i++)
            {
                std::vector<double> sampleList;

                if (mData.mIsComplexXform[i])
                {
                    readComplex(mCurTime, mData.mXformList[i], sampleList);
                }
                else
                {
                    Alembic::AbcGeom::XformSample samp;
                    read(mCurTime, mData.mXformList[i], sampleList, samp);
                }

                unsigned int sampleSize = (unsigned int)sampleList.size();

                for (unsigned int j = 0; j < sampleSize; j++)
                {
                    // only use the handle if it matches the index.
                    // The index wont line up in the sparse case so we
                    // can just skip that element.
                    if (outArrayHandle.elementIndex() == outHandleIndex++)
                    {
                        outHandle = outArrayHandle.outputValue(&status);
                    }
                    else
                        continue;

                    outArrayHandle.next();
                    outHandle.set(sampleList[j]);
                }
            }
            outArrayHandle.setAllClean();
        }
    }
    else if (plug == mOutLocatorPosScaleArrayAttr )
    {
        if (mOutRead[8])
        {
            dataBlock.setClean(plug);
            return MS::kSuccess;
        }

        mOutRead[8] = true;

        unsigned int locSize =
            static_cast<unsigned int>(mData.mLocList.size());

        if (locSize > 0)
        {
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutLocatorPosScaleArrayAttr, &status);

            MPlug arrayPlug(thisMObject(), mOutLocatorPosScaleArrayAttr);

            MDataHandle outHandle;
            unsigned int outHandleIndex = 0;

            for (unsigned int i = 0; i < locSize; i++)
            {
                std::vector< double > sampleList;
                read(mCurTime, mData.mLocList[i], sampleList);

                unsigned int sampleSize = (unsigned int)sampleList.size();
                for (unsigned int j = 0; j < sampleSize; j++)
                {
                    // only use the handle if it matches the index.
                    // The index wont line up in the sparse case so we
                    // can just skip that element.
                    if (outArrayHandle.elementIndex() == outHandleIndex++)
                    {
                        outHandle = outArrayHandle.outputValue(&status);
                    }
                    else
                        continue;

                    outArrayHandle.next();
                    outHandle.set(sampleList[j]);
                }
            }
            outArrayHandle.setAllClean();
        }
    }
    else if (plug == mOutSubDArrayAttr)
    {
        if (mOutRead[2])
        {
            // Reference the output to let EM know we are the writer
            // of the data. EM sets the output to holder and causes
            // race condition when evaluating fan-out destinations.
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutSubDArrayAttr, &status);
            const unsigned int elementCount = outArrayHandle.elementCount();
            for (unsigned int j = 0; j < elementCount; j++)
            {
                outArrayHandle.outputValue().data();
                outArrayHandle.next();
            }
            outArrayHandle.setAllClean();
            return MS::kSuccess;
        }

        mOutRead[2] = true;

        unsigned int subDSize =
            static_cast<unsigned int>(mData.mSubDList.size());

        if (subDSize > 0)
        {
            MArrayDataHandle outArrayHandle = dataBlock.outputValue(
                mOutSubDArrayAttr, &status);

            MDataHandle outHandle;

            for (unsigned int j = 0; j < subDSize; j++)
            {
                // these elements can be sparse if they have been deleted
                if (outArrayHandle.elementIndex() != j)
                {
                    continue;
                }

                outHandle = outArrayHandle.outputValue(&status);
                outArrayHandle.next();

                MObject obj = outHandle.data();
                if (obj.hasFn(MFn::kMesh))
                {
                    MFnMesh fnMesh(obj);
                    readSubD(mCurTime, fnMesh, obj, mData.mSubDList[j],
                        mSubDInitialized);
                    outHandle.set(obj);
                }
            }
            mSubDInitialized = true;
            outArrayHandle.setAllClean();
        }
        // for the case where we don't have any nodes, we want to make sure
        // to push out empty meshes on our connections, this can happen if
        // the input file was offlined, currently we only need to do this for
        // meshes as Nurbs, curves, and the other channels don't crash Maya
        else
        {
            MArrayDataHandle outArrayHandle = dataBlock.outputValue(
                mOutSubDArrayAttr, &status);

            if (outArrayHandle.elementCount() > 0)
            {
                do
                {
                    MDataHandle outHandle = outArrayHandle.outputValue();
                    MObject obj = outHandle.data();
                    if (obj.hasFn(MFn::kMesh))
                    {
                        MFloatPointArray emptyVerts;
                        MIntArray emptyCounts;
                        MIntArray emptyConnects;
                        MFnMesh emptyMesh;
                        emptyMesh.create(0, 0, emptyVerts, emptyCounts,
                            emptyConnects, obj);
                        outHandle.set(obj);
                    }
                }
                while (outArrayHandle.next() == MS::kSuccess);
            }
            mSubDInitialized = true;
            outArrayHandle.setAllClean();
        }
    }
    else if (plug == mOutPolyArrayAttr)
    {
        if (mOutRead[3])
        {
            // Reference the output to let EM know we are the writer
            // of the data. EM sets the output to holder and causes
            // race condition when evaluating fan-out destinations.
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutPolyArrayAttr, &status);
            const unsigned int elementCount = outArrayHandle.elementCount();
            for (unsigned int j = 0; j < elementCount; j++)
            {
                outArrayHandle.outputValue().data();
                outArrayHandle.next();
            }
            outArrayHandle.setAllClean();
            return MS::kSuccess;
        }

        mOutRead[3] = true;

        unsigned int polySize =
            static_cast<unsigned int>(mData.mPolyMeshList.size());

        if (polySize > 0)
        {
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutPolyArrayAttr, &status);

            MDataHandle outHandle;

            for (unsigned int j = 0; j < polySize; j++)
            {
                // these elements can be sparse if they have been deleted
                if (outArrayHandle.elementIndex() != j)
                {
                    continue;
                }

                outHandle = outArrayHandle.outputValue(&status);
                outArrayHandle.next();

                MObject obj = outHandle.data();
                if (obj.hasFn(MFn::kMesh))
                {
                    MFnMesh fnMesh(obj);
                    readPoly(mCurTime, fnMesh, obj, mData.mPolyMeshList[j],
                        mPolyInitialized);
                    outHandle.set(obj);
                }
            }
            mPolyInitialized = true;
            outArrayHandle.setAllClean();
        }
        // for the case where we don't have any nodes, we want to make sure
        // to push out empty meshes on our connections, this can happen if
        // the input file was offlined, currently we only need to do this for
        // meshes as Nurbs, curves, and the other channels don't crash Maya
        else
        {
            MArrayDataHandle outArrayHandle = dataBlock.outputValue(
                mOutPolyArrayAttr, &status);

            if (outArrayHandle.elementCount() > 0)
            {
                do
                {
                    MDataHandle outHandle = outArrayHandle.outputValue(&status);
                    MObject obj = outHandle.data();
                    if (obj.hasFn(MFn::kMesh))
                    {
                        MFloatPointArray emptyVerts;
                        MIntArray emptyCounts;
                        MIntArray emptyConnects;
                        MFnMesh emptyMesh;
                        emptyMesh.create(0, 0, emptyVerts, emptyCounts,
                            emptyConnects, obj);
                        outHandle.set(obj);
                    }
                }
                while (outArrayHandle.next() == MS::kSuccess);
            }
            mPolyInitialized = true;
            outArrayHandle.setAllClean();
        }
    }
    else if (plug == mOutCameraArrayAttr)
    {
        if (mOutRead[4])
        {
            dataBlock.setClean(plug);
            return MS::kSuccess;
        }

        mOutRead[4] = true;

        unsigned int cameraSize =
            static_cast<unsigned int>(mData.mCameraList.size());

        if (cameraSize > 0)
        {
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutCameraArrayAttr, &status);
            MPlug arrayPlug(thisMObject(), mOutCameraArrayAttr);
            double angleConversion = 1.0;

            switch (MAngle::uiUnit())
            {
                case MAngle::kRadians:
                    angleConversion = 0.017453292519943295;
                break;
                case MAngle::kAngMinutes:
                    angleConversion = 60.0;
                break;
                case MAngle::kAngSeconds:
                    angleConversion = 3600.0;
                break;
                default:
                break;
            }

            MDataHandle outHandle;
            unsigned int index = 0;

            for (unsigned int cameraIndex = 0; cameraIndex < cameraSize;
                cameraIndex++)
            {
                Alembic::AbcGeom::ICamera & cam =
                    mData.mCameraList[cameraIndex];
                std::vector<double> array;

                read(mCurTime, cam, array);

                for (unsigned int dataIndex = 0; dataIndex < array.size();
                    dataIndex++, index++)
                {
                    // skip over sparse elements
                    if (index != outArrayHandle.elementIndex())
                    {
                        continue;
                    }

                    outHandle = outArrayHandle.outputValue(&status);
                    outArrayHandle.next();

                    // not shutter angle index, so not an angle
                    if (dataIndex != 11)
                    {
                        outHandle.set(array[dataIndex]);
                    }
                    else
                    {
                        outHandle.set(array[dataIndex] * angleConversion);
                    }
                }  // for the per camera data handles
            }  // for each camera
            outArrayHandle.setAllClean();
        }
    }
    else if (plug == mOutNurbsSurfaceArrayAttr)
    {
        if (mOutRead[5])
        {
            // Reference the output to let EM know we are the writer
            // of the data. EM sets the output to holder and causes
            // race condition when evaluating fan-out destinations.
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutNurbsSurfaceArrayAttr, &status);
            const unsigned int elementCount = outArrayHandle.elementCount();
            for (unsigned int j = 0; j < elementCount; j++)
            {
                outArrayHandle.outputValue().data();
                outArrayHandle.next();
            }
            outArrayHandle.setAllClean();
            return MS::kSuccess;
        }

        mOutRead[5] = true;

        unsigned int nSurfaceSize =
            static_cast<unsigned int>(mData.mNurbsList.size());

        if (nSurfaceSize > 0)
        {
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutNurbsSurfaceArrayAttr, &status);

            MDataHandle outHandle;

            for (unsigned int j = 0; j < nSurfaceSize; j++)
            {
                // these elements can be sparse if they have been deleted
                if (outArrayHandle.elementIndex() != j)
                    continue;

                outHandle = outArrayHandle.outputValue(&status);
                outArrayHandle.next();

                MObject obj = outHandle.data();
                if (obj.hasFn(MFn::kNurbsSurface))
                {
                    readNurbs(mCurTime, mData.mNurbsList[j], obj);
                    outHandle.set(obj);
                }
            }
            outArrayHandle.setAllClean();
        }
    }
    else if (plug == mOutNurbsCurveGrpArrayAttr)
    {
        if (mOutRead[6])
        {
            // Reference the output to let EM know we are the writer
            // of the data. EM sets the output to holder and causes
            // race condition when evaluating fan-out destinations.
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutNurbsCurveGrpArrayAttr, &status);
            const unsigned int elementCount = outArrayHandle.elementCount();
            for (unsigned int j = 0; j < elementCount; j++)
            {
                outArrayHandle.outputValue().data();
                outArrayHandle.next();
            }
            outArrayHandle.setAllClean();
            return MS::kSuccess;
        }

        mOutRead[6] = true;

        unsigned int nCurveGrpSize =
            static_cast<unsigned int>(mData.mCurvesList.size());

        if (nCurveGrpSize > 0)
        {
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutNurbsCurveGrpArrayAttr, &status);
            MDataHandle outHandle;

            std::vector<MObject> curvesObj;
            for (unsigned int i = 0; i < nCurveGrpSize; ++i)
            {
                readCurves(mCurTime, mData.mCurvesList[i],
                    mData.mNumCurves[i], curvesObj);
            }

            std::size_t numChild = curvesObj.size();

            // not the best way to do this
            // only reading bunches of curves based on the connections would be
            // more efficient when there is a bunch of broken connections
            for (unsigned int i = 0; i < numChild; i++)
            {
                if (outArrayHandle.elementIndex() != i)
                {
                    continue;
                }

                outHandle = outArrayHandle.outputValue(&status);
                outArrayHandle.next();
                status = outHandle.set(curvesObj[i]);
            }

            outArrayHandle.setAllClean();
        }
    }
    else
    {
        return MS::kUnknownParameter;
    }

    dataBlock.setClean(plug);
    return status;
}
Exemplo n.º 3
0
// Method reads one wireframe body-element from Ideas univ. file dataset
// and adds body-element into body/model.   
// Returns: 1=new body was created, 0=old body was updateds, -1 = end-of-odataset.
int
InputIdeasWF::readWireFrameBody()
{
  Body* body;

  // We want to start from this position, when the body-read loop is started!
  //streampos cur_pos = infile.tellg();
 
  // =====Read body ID, CODE and NAME (from color code!) ( Record-1).
  readFileLine(infile, read_buffer);

  // However, check first that ***end-of-datset*** (-1) is not encountered
  // In this case dataset is empty!
  if (endofDataset(read_buffer))
    return -1;

  // Now read id, code and name.
  //char* name = readBodyName(read_buffer);
  int id_nbr = readBodyNbr(read_buffer);
  char* name = NULL;

  // =====Read CURVE-TYPE information ( Record-2).
  readFileLine(infile, read_buffer);
  ecif_geometryType g_type = readGeomType(read_buffer);

  // Back to body's starting position!
  //infile.seekg(cur_pos);

  // We check if we are reading new pieces for an old body!
  // Checking is based on a *local table* where we have id-numbers
  // from the file (id_nbr) and system (automagically) generated
  // technical id-numbers (body->Tag()) as pairs.
  bool isNewBody = false;
  IdNumberTable::iterator itr = bodyNumbers.find(id_nbr);

  // Old body
  if (itr != bodyNumbers.end())
    body = model->getBodyByTag((*itr).second);

  // Create a new body  
  else {
    colorIndices color = (colorIndices)id_nbr; // id_nbr is read from color code!

    //2D geometry
    if (modelDimension == ECIF_2D)
      body = new Body2D(GEOM_BODY, id_nbr, name, color);

    //3D geometry
    else if (modelDimension == ECIF_3D)
        body = new Body3D(GEOM_BODY, id_nbr, name, color);

    model->addBody(body);

    isNewBody = true;
    bodyNumbers[id_nbr] = body->Tag();
  }

  // How to read depends on the geometry-type:
  switch (g_type) {
  case ECIF_LINE:
    readLine(body, read_buffer);
    break;
  case ECIF_NURBS:
    readNurbs(body, read_buffer);
    break;
  default:
    break;
  }

  if (isNewBody)
    return 1;
  else
    return 0;
}