Abc::FloatArraySamplePtr getKnotVector(AbcG::ICurves& obj) { ESS_PROFILE_FUNC(); Abc::ICompoundProperty arbGeom = obj.getSchema().getArbGeomParams(); if (!arbGeom.valid()) { return Abc::FloatArraySamplePtr(); } if (arbGeom.getPropertyHeader(".knot_vectors") != NULL) { Abc::IFloatArrayProperty knotProp = Abc::IFloatArrayProperty(arbGeom, ".knot_vectors"); if (knotProp.valid() && knotProp.getNumSamples() != 0) { return knotProp.getValue(0); } } if (arbGeom.getPropertyHeader(".knot_vector") != NULL) { Abc::IFloatArrayProperty knotProp = Abc::IFloatArrayProperty(arbGeom, ".knot_vector"); if (knotProp.valid() && knotProp.getNumSamples() != 0) { return knotProp.getValue(0); } } return Abc::FloatArraySamplePtr(); }
Abc::UInt16ArraySamplePtr getCurveOrders(AbcG::ICurves& obj) { ESS_PROFILE_FUNC(); Abc::ICompoundProperty arbGeom = obj.getSchema().getArbGeomParams(); if(!arbGeom.valid()){ return Abc::UInt16ArraySamplePtr(); } if ( arbGeom.getPropertyHeader( ".orders" ) != NULL ){ Abc::IUInt16ArrayProperty orders = Abc::IUInt16ArrayProperty( arbGeom, ".orders" ); if(orders.valid() && orders.getNumSamples() != 0){ return orders.getValue(0); } } return Abc::UInt16ArraySamplePtr(); }
MStatus AlembicCurvesLocatorNode::compute(const MPlug &plug, MDataBlock &dataBlock) { ESS_PROFILE_SCOPE("AlembicCurvesLocatorNode::compute"); MStatus status; // update the frame number to be imported double inputTime = dataBlock.inputValue(mTimeAttr).asTime().as(MTime::kSeconds); MString &fileName = dataBlock.inputValue(mFileNameAttr).asString(); MString &identifier = dataBlock.inputValue(mIdentifierAttr).asString(); AbcG::ICurves obj; // check if we have the file if (fileName != mFileName || identifier != mIdentifier) { mSchema.reset(); if (fileName != mFileName) { delRefArchive(mFileName); mFileName = fileName; addRefArchive(mFileName); } mIdentifier = identifier; // get the object from the archive Abc::IObject iObj = getObjectFromArchive(mFileName, identifier); if (!iObj.valid()) { MGlobal::displayWarning("[ExocortexAlembic] Identifier '" + identifier + "' not found in archive '" + mFileName + "'."); return MStatus::kFailure; } obj = AbcG::ICurves(iObj, Abc::kWrapExisting); if (!obj.valid()) { MGlobal::displayWarning("[ExocortexAlembic] Identifier '" + identifier + "' in archive '" + mFileName + "' is not a Curves."); return MStatus::kFailure; } mSchema = obj.getSchema(); } if (!mSchema.valid()) { return MStatus::kFailure; } // get the sample SampleInfo sampleInfo = getSampleInfo(inputTime, mSchema.getTimeSampling(), mSchema.getNumSamples()); // check if we have to do this at all if (mNbCurves == 0 || mLastSampleInfo.floorIndex != sampleInfo.floorIndex || mLastSampleInfo.ceilIndex != sampleInfo.ceilIndex) { AbcG::ICurvesSchema::Sample sample; AbcG::ICurvesSchema::Sample sample2; mSchema.get(sample, sampleInfo.floorIndex); if (sampleInfo.alpha != 0.0) { mSchema.get(sample2, sampleInfo.ceilIndex); } // update the indices Abc::P3fArraySamplePtr samplePos = sample.getPositions(); if (mNbCurves != sample.getNumCurves() || mNbVertices != samplePos->size()) { mNbCurves = (unsigned int)sample.getNumCurves(); mNbVertices = (unsigned int)samplePos->size(); Abc::Int32ArraySamplePtr nbVertices = sample.getCurvesNumVertices(); mIndices.clear(); unsigned int offset = 0; for (unsigned int i = 0; i < mNbCurves; i++) { unsigned int verticesPerCurve = nbVertices->get()[i]; for (unsigned j = 0; j < verticesPerCurve - 1; j++) { mIndices.push_back(offset); offset++; mIndices.push_back(offset); } offset++; } } if (mPositions.size() != samplePos->size()) { mPositions.resize(samplePos->size()); } // check if we need to interpolate bool done = false; mBoundingBox.clear(); if (sampleInfo.alpha != 0.0) { Abc::P3fArraySamplePtr samplePos2 = sample2.getPositions(); if (samplePos->size() == samplePos2->size()) { float alpha = float(sampleInfo.alpha); float ialpha = 1.0f - alpha; for (unsigned int i = 0; i < samplePos->size(); i++) { mPositions[i].x = ialpha * samplePos->get()[i].x + alpha * samplePos2->get()[i].x; mPositions[i].y = ialpha * samplePos->get()[i].y + alpha * samplePos2->get()[i].y; mPositions[i].z = ialpha * samplePos->get()[i].z + alpha * samplePos2->get()[i].z; mBoundingBox.expand( MPoint(mPositions[i].x, mPositions[i].y, mPositions[i].z)); } done = true; } } if (!done) { for (unsigned int i = 0; i < samplePos->size(); i++) { mPositions[i].x = samplePos->get()[i].x; mPositions[i].y = samplePos->get()[i].y; mPositions[i].z = samplePos->get()[i].z; mBoundingBox.expand( MPoint(mPositions[i].x, mPositions[i].y, mPositions[i].z)); } } // get the colors // mColors.clear(); Abc::IC4fArrayProperty propColor; if (getArbGeomParamPropertyAlembic(obj, "color", propColor)) { mColors.clear(); SampleInfo colorSampleInfo = getSampleInfo( inputTime, propColor.getTimeSampling(), propColor.getNumSamples()); Abc::C4fArraySamplePtr sampleColor = propColor.getValue(colorSampleInfo.floorIndex); mColors.resize(mPositions.size()); if (sampleColor->size() == 1) { for (unsigned int i = 0; i < (unsigned int)mColors.size(); i++) { mColors[i].r = sampleColor->get()[0].r; mColors[i].g = sampleColor->get()[0].g; mColors[i].b = sampleColor->get()[0].b; mColors[i].a = sampleColor->get()[0].a; } } else if (sampleColor->size() == mPositions.size()) { for (unsigned int i = 0; i < sampleColor->size(); i++) { mColors[i].r = sampleColor->get()[i].r; mColors[i].g = sampleColor->get()[i].g; mColors[i].b = sampleColor->get()[i].b; mColors[i].a = sampleColor->get()[i].a; } } else if (sampleColor->size() == mNbCurves) { Abc::Int32ArraySamplePtr nbVertices = sample.getCurvesNumVertices(); unsigned int offset = 0; for (unsigned int i = 0; i < nbVertices->size(); i++) { for (unsigned j = 0; j < (unsigned int)nbVertices->get()[i]; j++) { mColors[offset].r = sampleColor->get()[i].r; mColors[offset].g = sampleColor->get()[i].g; mColors[offset].b = sampleColor->get()[i].b; mColors[offset].a = sampleColor->get()[i].a; offset++; } } } } } mLastSampleInfo = sampleInfo; MDataHandle outSent = dataBlock.outputValue(mSentinelAttr); // increment, this tells the draw routine that the display list needs to be // regenerated outSent.set((mSent + 1 % 10)); dataBlock.setClean(mSentinelAttr); return MStatus::kSuccess; }