//-***************************************************************************** // // Copyright (c) 2009-2012, // Sony Pictures Imageworks Inc. and // Industrial Light & Magic, a division of Lucasfilm Entertainment Company Ltd. // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Sony Pictures Imageworks, nor // Industrial Light & Magic, nor the names of their contributors may be used // to endorse or promote products derived from this software without specific // prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // //-***************************************************************************** #include "MayaPointPrimitiveWriter.h" #include "MayaUtility.h" #include namespace AbcGeom = Alembic::AbcGeom; MayaPointPrimitiveWriter::MayaPointPrimitiveWriter( double iFrame, MDagPath & iDag, Alembic::AbcGeom::OObject & iParent, Alembic::Util::uint32_t iTimeIndex, const JobArgs & iArgs) : mIsAnimated(false), mDagPath(iDag) { MFnParticleSystem particle(mDagPath); MString name = particle.name(); name = util::stripNamespaces(name, iArgs.stripNamespace); Alembic::AbcGeom::OPoints obj(iParent, name.asChar(), iTimeIndex); mSchema = obj.getSchema(); Alembic::Abc::OCompoundProperty cp; Alembic::Abc::OCompoundProperty up; if (AttributesWriter::hasAnyAttr(particle, iArgs)) { cp = mSchema.getArbGeomParams(); up = mSchema.getUserProperties(); } mAttrs = AttributesWriterPtr(new AttributesWriter(cp, up, obj, particle, iTimeIndex, iArgs, true)); MObject object = iDag.node(); if (iTimeIndex != 0 && util::isAnimated(object)) { mIsAnimated = true; } if (!mIsAnimated || iArgs.setFirstAnimShape) { write(iFrame); } } void MayaPointPrimitiveWriter::write(double iFrame) { MStatus status; std::vector position; std::vector velocity; std::vector< Alembic::Util::uint64_t > particleIds; std::vector width; bool runupFromStart = false; MTime to(iFrame, MTime::kSeconds); // need to force re-evaluation MFnParticleSystem particle(mDagPath); particle.evaluateDynamics(to, runupFromStart); unsigned int size = particle.count(); Alembic::AbcGeom::OPointsSchema::Sample samp; if (size == 0) { samp.setPositions(Alembic::Abc::V3fArraySample(NULL, 0)); samp.setVelocities(Alembic::Abc::V3fArraySample(NULL, 0)); samp.setIds(Alembic::Abc::UInt64ArraySample(NULL, 0)); mSchema.set(samp); return; } position.reserve(size*3); velocity.reserve(size*3); particleIds.reserve(size); width.reserve(size); // get particle position MVectorArray posArray; particle.position(posArray); for (unsigned int i = 0; i < size; i++) { MVector vec = posArray[i]; position.push_back(static_cast(vec.x)); position.push_back(static_cast(vec.y)); position.push_back(static_cast(vec.z)); } samp.setPositions( Alembic::Abc::P3fArraySample((const Imath::V3f *) &position.front(), position.size() / 3) ); // get particle velocity MVectorArray vecArray; particle.velocity(vecArray); for (unsigned int i = 0; i < size; i++) { MVector vec = vecArray[i]; velocity.push_back(static_cast(vec.x)); velocity.push_back(static_cast(vec.y)); velocity.push_back(static_cast(vec.z)); } if (!velocity.empty()) { samp.setVelocities( Alembic::Abc::V3fArraySample((const Imath::V3f *) &velocity.front(), velocity.size() / 3) ); } // get particleIds MIntArray idArray; particle.particleIds(idArray); for (unsigned int i = 0; i < size; i++) { particleIds.push_back(idArray[i]); } samp.setIds( Alembic::Abc::UInt64ArraySample(&(particleIds.front()), particleIds.size()) ); // assume radius is width MDoubleArray radiusArray; MPlug radius = particle.findPlug("radiusPP", true, &status); AbcGeom::GeometryScope widthScope = AbcGeom::kUnknownScope; if ( status == MS::kSuccess) { // RadiusPP exists, get all particles value widthScope = AbcGeom::kVaryingScope; particle.radius(radiusArray); for (unsigned int i = 0; i < size; i++) { float radius = static_cast(radiusArray[i]); width.push_back(radius); } } else { // Get the value of the radius attribute widthScope = AbcGeom::kUniformScope; width.push_back( particle.findPlug("radius", true).asDouble() ); } if (!width.empty()) { Alembic::AbcGeom::OFloatGeomParam::Sample widthSamp; widthSamp.setVals(width); widthSamp.setScope(widthScope); samp.setWidths( widthSamp ); } mSchema.set(samp); } unsigned int MayaPointPrimitiveWriter::getNumCVs() { MFnParticleSystem particle(mDagPath); return particle.count(); } bool MayaPointPrimitiveWriter::isAnimated() const { return mIsAnimated; }