Example #1
0
MObject createSubD(double iFrame, SubDAndColors & iNode,
    MObject & iParent)
{
    Alembic::AbcGeom::ISubDSchema schema = iNode.mMesh.getSchema();

    Alembic::AbcCoreAbstract::index_t index, ceilIndex;
    getWeightAndIndex(iFrame, schema.getTimeSampling(),
        schema.getNumSamples(), index, ceilIndex);

    Alembic::AbcGeom::ISubDSchema::Sample samp;
    schema.get(samp, Alembic::Abc::ISampleSelector(index));

    MString name(iNode.mMesh.getName().c_str());

    MFnMesh fnMesh;

    MFloatPointArray pointArray;
    Alembic::Abc::P3fArraySamplePtr emptyPtr;
    fillPoints(pointArray, samp.getPositions(), emptyPtr, 0.0);

    fillTopology(fnMesh, iParent, pointArray, samp.getFaceIndices(),
        samp.getFaceCounts());
    fnMesh.setName(iNode.mMesh.getName().c_str());

    setInitialShadingGroup(fnMesh.partialPathName());

    MObject obj = fnMesh.object();

    setUVs(iFrame, fnMesh, schema.getUVsParam());

    setColors(iFrame, fnMesh, iNode.mC3s, iNode.mC4s, true);

    // add the mFn-specific attributes to fnMesh node
    MFnNumericAttribute numAttr;
    MString attrName("SubDivisionMesh");
    MObject attrObj = numAttr.create(attrName, attrName,
        MFnNumericData::kBoolean, 1);
    numAttr.setKeyable(true);
    numAttr.setHidden(false);
    fnMesh.addAttribute(attrObj, MFnDependencyNode::kLocalDynamicAttr);

    if (samp.getInterpolateBoundary() > 0)
    {
        attrName = MString("interpolateBoundary");
        attrObj = numAttr.create(attrName, attrName, MFnNumericData::kBoolean,
            samp.getInterpolateBoundary());

        numAttr.setKeyable(true);
        numAttr.setHidden(false);
        fnMesh.addAttribute(attrObj,  MFnDependencyNode::kLocalDynamicAttr);
    }

    if (samp.getFaceVaryingInterpolateBoundary() > 0)
    {
        attrName = MString("faceVaryingInterpolateBoundary");
        attrObj = numAttr.create(attrName, attrName, MFnNumericData::kBoolean,
            samp.getFaceVaryingInterpolateBoundary());

        numAttr.setKeyable(true);
        numAttr.setHidden(false);
        fnMesh.addAttribute(attrObj,  MFnDependencyNode::kLocalDynamicAttr);
    }

    if (samp.getFaceVaryingPropagateCorners() > 0)
    {
        attrName = MString("faceVaryingPropagateCorners");
        attrObj = numAttr.create(attrName, attrName, MFnNumericData::kBoolean,
            samp.getFaceVaryingPropagateCorners());

        numAttr.setKeyable(true);
        numAttr.setHidden(false);
        fnMesh.addAttribute(attrObj,  MFnDependencyNode::kLocalDynamicAttr);
    }

#if MAYA_API_VERSION >= 201100
    Alembic::Abc::Int32ArraySamplePtr holes = samp.getHoles();
    if (holes && !holes->size() == 0)
    {
        unsigned int numHoles = (unsigned int)holes->size();
        MUintArray holeData(numHoles);
        for (unsigned int i = 0; i < numHoles; ++i)
        {
            holeData[i] = (*holes)[i];
        }

        if (fnMesh.setInvisibleFaces(holeData) != MS::kSuccess)
        {
            MString warn = "Failed to set holes on: ";
            warn += iNode.mMesh.getName().c_str();
            printWarning(warn);
        }
    }
#endif

    Alembic::Abc::FloatArraySamplePtr creases = samp.getCreaseSharpnesses();
    if (creases && !creases->size() == 0)
    {
        Alembic::Abc::Int32ArraySamplePtr indices = samp.getCreaseIndices();
        Alembic::Abc::Int32ArraySamplePtr lengths = samp.getCreaseLengths();
        std::size_t numLengths = lengths->size();

        MUintArray edgeIds;
        MDoubleArray creaseData;

        std::size_t curIndex = 0;
        // curIndex incremented here to move on to the next crease length
        for (std::size_t i = 0; i < numLengths; ++i, ++curIndex)
        {
            std::size_t len = (*lengths)[i] - 1;
            float creaseSharpness = (*creases)[i];

            // curIndex incremented here to go between all the edges that make
            // up a given length
            for (std::size_t j = 0; j < len; ++j, ++curIndex)
            {
                Alembic::Util::int32_t vertA = (*indices)[curIndex];
                Alembic::Util::int32_t vertB = (*indices)[curIndex+1];
                MItMeshVertex itv(obj);

                int prev;
                itv.setIndex(vertA, prev);

                MIntArray edges;
                itv.getConnectedEdges(edges);
                std::size_t numEdges = edges.length();
                for (unsigned int k = 0; k < numEdges; ++k)
                {
                    int oppVert = -1;
                    itv.getOppositeVertex(oppVert, edges[k]);
                    if (oppVert == vertB)
                    {
                        creaseData.append(creaseSharpness);
                        edgeIds.append(edges[k]);
                        break;
                    }
                }
            }
        }
        if (fnMesh.setCreaseEdges(edgeIds, creaseData) != MS::kSuccess)
        {
            MString warn = "Failed to set creases on: ";
            warn += iNode.mMesh.getName().c_str();
            printWarning(warn);
        }
    }

    Alembic::Abc::FloatArraySamplePtr corners = samp.getCornerSharpnesses();
    if (corners && !corners->size() == 0)
    {
        Alembic::Abc::Int32ArraySamplePtr cornerVerts = samp.getCornerIndices();
        unsigned int numCorners = static_cast<unsigned int>(corners->size());
        MUintArray vertIds(numCorners);
        MDoubleArray cornerData(numCorners);

        for (unsigned int i = 0; i < numCorners; ++i)
        {
            cornerData[i] = (*corners)[i];
            vertIds[i] = (*cornerVerts)[i];
        }
        if (fnMesh.setCreaseVertices(vertIds, cornerData) != MS::kSuccess)
        {
            MString warn = "Failed to set corners on: ";
            warn += iNode.mMesh.getName().c_str();
            printWarning(warn);
        }
    }

    return obj;
}
Example #2
0
AtNode *createCurvesNode(nodeData &nodata, userData * ud, std::vector<float> &samples, int i)
{
  Alembic::AbcGeom::ICurves typedObject(nodata.object, Alembic::Abc::kWrapExisting);
  size_t minNumSamples = typedObject.getSchema().getNumSamples() == 1 ? typedObject.getSchema().getNumSamples() : samples.size();

  shiftedProcessing(nodata, ud);

  AtNode *shapeNode = AiNode("curves");
  nodata.createdShifted = false;

  // create arrays to hold the data
  AtArray *pos = NULL;

  // loop over all samples
  AtULong posOffset = 0;
  size_t totalNumPoints =  0;
  size_t totalNumPositions = 0;
  for(size_t sampleIndex = 0; sampleIndex < minNumSamples; ++sampleIndex)
  {
    SampleInfo sampleInfo = getSampleInfo(
      samples[sampleIndex],
      typedObject.getSchema().getTimeSampling(),
      typedObject.getSchema().getNumSamples()
    );

    // get the floor sample
    Alembic::AbcGeom::ICurvesSchema::Sample sample;
    typedObject.getSchema().get(sample,sampleInfo.floorIndex);

    // access the num points
    Alembic::Abc::Int32ArraySamplePtr abcNumPoints = sample.getCurvesNumVertices();

    // take care of the topology
    if(sampleIndex == 0)
    {
      // hard coded pixel width, basis and mode
      AiNodeSetFlt(shapeNode, "min_pixel_width", 0.25f);
      AiNodeSetStr(shapeNode, "basis", "catmull-rom");
      AiNodeSetStr(shapeNode, "mode", ud->gCurvesMode.c_str());

      // setup the num_points
      AtArray * numPoints = AiArrayAllocate((AtInt)abcNumPoints->size(),1,AI_TYPE_UINT);
      for(size_t i=0;i<abcNumPoints->size();i++)
      {
        totalNumPoints += abcNumPoints->get()[i];
        totalNumPositions += abcNumPoints->get()[i] + 2;
        AiArraySetUInt(numPoints,(AtULong)i,(AtUInt)(abcNumPoints->get()[i]+2));
      }
      AiNodeSetArray(shapeNode,"num_points",numPoints);

      // check if we have a radius
      Alembic::Abc::IFloatArrayProperty propRadius;
			if( getArbGeomParamPropertyAlembic( typedObject, "radius", propRadius ) )
      {
        Alembic::Abc::FloatArraySamplePtr abcRadius = propRadius.getValue(sampleInfo.floorIndex);

        AtArray * radius = AiArrayAllocate((AtInt)abcRadius->size(),1,AI_TYPE_FLOAT);
        for(size_t i=0; i < abcRadius->size(); ++i)
          AiArraySetFlt(radius,(AtULong)i,abcRadius->get()[i]);
        AiNodeSetArray(shapeNode,"radius",radius);
      }

      // check if we have uvs
      Alembic::AbcGeom::IV2fGeomParam uvsParam = typedObject.getSchema().getUVsParam();
      if(uvsParam.valid())
      {
        Alembic::Abc::V2fArraySamplePtr abcUvs = uvsParam.getExpandedValue(sampleInfo.floorIndex).getVals();
        if(AiNodeDeclare(shapeNode, "Texture_Projection", "uniform POINT2"))
        {
          AtArray* uvs = AiArrayAllocate((AtInt)abcUvs->size(), 1, AI_TYPE_POINT2);
          AtPoint2 uv;
          for(size_t i=0; i<abcUvs->size(); i++)
          {
            uv.x = abcUvs->get()[i].x;
            uv.y = abcUvs->get()[i].y;
            AiArraySetPnt2(uvs, (AtULong)i, uv);
          }
          AiNodeSetArray(shapeNode, "Texture_Projection", uvs);
        }
      }

      // check if we have colors
      Alembic::Abc::IC4fArrayProperty propColor;
			if( getArbGeomParamPropertyAlembic( typedObject, "color", propColor ) )
      {
        Alembic::Abc::C4fArraySamplePtr abcColors = propColor.getValue(sampleInfo.floorIndex);
        AtBoolean result = false;
        if(abcColors->size() == 1)
          result = AiNodeDeclare(shapeNode, "Color", "constant RGBA");
        else if(abcColors->size() == abcNumPoints->size())
          result = AiNodeDeclare(shapeNode, "Color", "uniform RGBA");
        else
          result = AiNodeDeclare(shapeNode, "Color", "varying RGBA");

        if(result)
        {
          AtArray * colors = AiArrayAllocate((AtInt)abcColors->size(), 1, AI_TYPE_RGBA);
          AtRGBA color;
          for(size_t i=0; i<abcColors->size(); ++i)
          {
            color.r = abcColors->get()[i].r;
            color.g = abcColors->get()[i].g;
            color.b = abcColors->get()[i].b;
            color.a = abcColors->get()[i].a;
            AiArraySetRGBA(colors, (AtULong)i, color);
          }
          AiNodeSetArray(shapeNode, "Color", colors);
        }
      }
    }

    // access the positions
    Alembic::Abc::P3fArraySamplePtr abcPos = sample.getPositions();
    if(pos == NULL)
      pos = AiArrayAllocate((AtInt)(totalNumPositions * 3),(AtInt)minNumSamples,AI_TYPE_FLOAT);

    // if we have to interpolate
    bool done = false;
    if(sampleInfo.alpha > sampleTolerance)
    {
      Alembic::AbcGeom::ICurvesSchema::Sample sample2;
      typedObject.getSchema().get(sample2,sampleInfo.ceilIndex);
      Alembic::Abc::P3fArraySamplePtr abcPos2 = sample2.getPositions();
      float alpha = (float)sampleInfo.alpha;
      float ialpha = 1.0f - alpha;
      size_t offset = 0;
      if(abcPos2->size() == abcPos->size())
      {
        for(size_t i=0; i<abcNumPoints->size(); ++i)
        {
          // add the first and last point manually (catmull clark)
          for(size_t j=0; j<abcNumPoints->get()[i]; ++j)
          {
            AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].x * ialpha + abcPos2->get()[offset].x * alpha);
            AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].y * ialpha + abcPos2->get()[offset].y * alpha);
            AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].z * ialpha + abcPos2->get()[offset].z * alpha);
            if(j==0 || j == abcNumPoints->get()[i]-1)
            {
              AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].x * ialpha + abcPos2->get()[offset].x * alpha);
              AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].y * ialpha + abcPos2->get()[offset].y * alpha);
              AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].z * ialpha + abcPos2->get()[offset].z * alpha);
            }
            ++offset;
          }
        }
        done = true;
      }
      else
      {
        Alembic::Abc::P3fArraySamplePtr abcVel = sample.getPositions();
        if(abcVel)
        {
          if(abcVel->size() == abcPos->size())
          {
            for(size_t i=0; i<abcNumPoints->size(); ++i)
            {
              // add the first and last point manually (catmull clark)
              for(size_t j=0; j<abcNumPoints->get()[i]; ++j)
              {
                AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].x + abcVel->get()[offset].x * alpha);
                AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].y + abcVel->get()[offset].y * alpha);
                AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].z + abcVel->get()[offset].z * alpha);
                if(j==0 || j == abcNumPoints->get()[i]-1)
                {
                  AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].x + abcVel->get()[offset].x * alpha);
                  AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].y + abcVel->get()[offset].y * alpha);
                  AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].z + abcVel->get()[offset].z * alpha);
                }
                ++offset;
              }
            }
            done = true;
          }
        }
      }
    }

    if(!done)
    {
      size_t offset = 0;
      for(size_t i=0; i<abcNumPoints->size(); ++i)
      {
        // add the first and last point manually (catmull clark)
        for(size_t j=0; j<abcNumPoints->get()[i]; ++j)
        {
          AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].x);
          AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].y);
          AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].z);
          if(j==0 || j == abcNumPoints->get()[i]-1)
          {
            AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].x);
            AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].y);
            AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].z);
          }
          ++offset;
        }
      }
    }
  }

  AiNodeSetArray(shapeNode, "points", pos);
  return shapeNode;
}