예제 #1
0
void MayaMeshWriter::write()
{

    MStatus status = MS::kSuccess;
    MFnMesh lMesh( mDagPath, &status );
    if ( !status )
    {
        MGlobal::displayError( "MFnMesh() failed for MayaMeshWriter" );
    }

    Alembic::AbcGeom::OV2fGeomParam::Sample uvSamp;
    std::vector<float> uvs;
    std::vector<Alembic::Util::uint32_t> indices;
    std::string uvSetName;

    if (mWriteUVs || mWriteUVSets)
    {
        getUVs(uvs, indices, uvSetName);

        if (!uvs.empty())
        {
            if (!uvSetName.empty())
            {
                if (mPolySchema.valid())
                {
                    mPolySchema.setUVSourceName(uvSetName);
                }
                else if (mSubDSchema.valid())
                {
                    mSubDSchema.setUVSourceName(uvSetName);
                }
            }
            uvSamp.setScope( Alembic::AbcGeom::kFacevaryingScope );
            uvSamp.setVals(Alembic::AbcGeom::V2fArraySample(
                (const Imath::V2f *) &uvs.front(), uvs.size() / 2));
            if (!indices.empty())
            {
                uvSamp.setIndices(Alembic::Abc::UInt32ArraySample(
                    &indices.front(), indices.size()));
            }
        }
    }

    std::vector<float> points;
    std::vector<Alembic::Util::int32_t> facePoints;
    std::vector<Alembic::Util::int32_t> faceList;

    if (mPolySchema.valid())
    {
        writePoly(uvSamp);
    }
    else if (mSubDSchema.valid())
    {
        writeSubD(uvSamp);
    }
}
예제 #2
0
파일: alembic.cpp 프로젝트: tsks/mmdbridge
static void export_alembic_xform_by_buffer(AlembicArchive &archive, const RenderedBuffer & renderedBuffer, int renderedBufferIndex)
{
	Alembic::AbcGeom::OObject topObj(*archive.archive, Alembic::AbcGeom::kTop);

	Alembic::AbcGeom::OXform xform;
	if (archive.xform_map.find(renderedBufferIndex) != archive.xform_map.end())
	{
		xform = archive.xform_map[renderedBufferIndex];
	}
	else
	{
		xform = Alembic::AbcGeom::OXform(topObj, "xform_" + umbase::UMStringUtil::number_to_string(renderedBufferIndex), archive.timesampling);
		archive.xform_map[renderedBufferIndex] = xform;
	}
		
	bool isFirstMesh = false;
	Alembic::AbcGeom::OPolyMesh polyMesh;
	if (archive.mesh_map.find(renderedBufferIndex) != archive.mesh_map.end())
	{
		polyMesh = archive.mesh_map[renderedBufferIndex];
	}
	else
	{
		polyMesh = Alembic::AbcGeom::OPolyMesh(xform, "mesh_" + to_string(renderedBufferIndex), archive.timesampling);
		archive.mesh_map[renderedBufferIndex] = polyMesh;
		isFirstMesh = true;

		Alembic::AbcGeom::OPolyMeshSchema &meshSchema = polyMesh.getSchema();
		archive.schema_map[renderedBufferIndex] = meshSchema;
	}

	Alembic::AbcGeom::OPolyMeshSchema &meshSchema = archive.schema_map[renderedBufferIndex];
	meshSchema.setTimeSampling(archive.timesampling);
		
	std::vector<Alembic::Util::int32_t> faceList;
	std::vector<Alembic::Util::int32_t> faceCountList;
		
	const RenderedBuffer::UVList &uvList = renderedBuffer.uvs;
	const RenderedBuffer::VertexList &vertexList = renderedBuffer.vertecies;
	const RenderedBuffer::NormalList &normalList =  renderedBuffer.normals;
	RenderedBuffer::UVList& temporary_uv = archive.temporary_uv_list;
	temporary_uv.resize(uvList.size());
	RenderedBuffer::NormalList& temporary_normal = archive.temporary_normal_list;
	temporary_normal.resize(normalList.size());
	RenderedBuffer::VertexList& temporary_vertex = archive.temporary_vertex_list;
	temporary_vertex.resize(vertexList.size());

	const int materialSize = static_cast<int>(renderedBuffer.materials.size());

	int totalFaceCount = 0;
	for (int k = 0; k < materialSize; ++k)
	{
		RenderedMaterial* material = renderedBuffer.materials.at(k);
		totalFaceCount += material->surface.faces.size();
	}
		
	if (archive.surface_size_map.find(renderedBufferIndex) == archive.surface_size_map.end())
	{
		archive.surface_size_map[renderedBufferIndex] = 0;
	}
	int& preSurfaceSize = archive.surface_size_map[renderedBufferIndex];
	bool isFirstSurface = totalFaceCount != preSurfaceSize;
	if (!isFirstMesh && isFirstSurface)
	{
		return;
	}
	preSurfaceSize = totalFaceCount;

	faceCountList.resize(totalFaceCount);
	faceList.resize(totalFaceCount * 3);

	int faceCounter = 0;
	for (int k = 0; k < materialSize; ++k)
	{
		RenderedMaterial* material = renderedBuffer.materials.at(k);
		const int faceSize = material->surface.faces.size();
		for (int n = 0; n < faceSize; ++n)
		{
			UMVec3i face = material->surface.faces[n];
			faceList[faceCounter * 3 + 0] = (face.x - 1);
			faceList[faceCounter * 3 + 1] = (face.y - 1);
			faceList[faceCounter * 3 + 2] = (face.z - 1);
			faceCountList[faceCounter] = 3;
			++faceCounter;
		}
	}

	Alembic::AbcGeom::OPolyMeshSchema::Sample sample;
				
	// vertex
	for (int n = 0, nsize = vertexList.size(); n < nsize; ++n)
	{
		temporary_vertex[n].z = -vertexList[n].z;
	}
	Alembic::AbcGeom::P3fArraySample positions( (const Imath::V3f *) &temporary_vertex.front(), temporary_vertex.size());
	sample.setPositions(positions);
				
	// face index
	if (isFirstMesh)
	{
		Alembic::Abc::Int32ArraySample faceIndices(faceList);
		Alembic::Abc::Int32ArraySample faceCounts(faceCountList);
		sample.setFaceIndices(faceIndices);
		sample.setFaceCounts(faceCounts);
	}

	// UVs
	if (!uvList.empty() && archive.is_export_uvs)
	{
		for (int n = 0, nsize = uvList.size(); n < nsize; ++n)
		{
			temporary_uv[n].y = 1.0f - uvList[n].y;
		}
		Alembic::AbcGeom::OV2fGeomParam::Sample uvSample;
		uvSample.setScope(Alembic::AbcGeom::kVertexScope );
		uvSample.setVals(Alembic::AbcGeom::V2fArraySample( ( const Imath::V2f *) &temporary_uv.front(), temporary_uv.size()));
		sample.setUVs(uvSample);
	}

	// Normals
	if (!normalList.empty() && archive.is_export_normals)
	{
		for (int n = 0, nsize = normalList.size(); n < nsize; ++n)
		{
			temporary_normal[n].z = -normalList[n].z;
		}
		Alembic::AbcGeom::ON3fGeomParam::Sample normalSample;
		normalSample.setScope(Alembic::AbcGeom::kVertexScope );
		normalSample.setVals(Alembic::AbcGeom::N3fArraySample( (const Alembic::AbcGeom::N3f *) &temporary_normal.front(), temporary_normal.size()));
		sample.setNormals(normalSample);
	}

	meshSchema.set(sample);

}
예제 #3
0
MayaMeshWriter::MayaMeshWriter(MDagPath & iDag,
    Alembic::Abc::OObject & iParent, Alembic::Util::uint32_t iTimeIndex,
    const JobArgs & iArgs, GetMembersMap& gmMap)
  : mNoNormals(iArgs.noNormals),
    mWriteUVs(iArgs.writeUVs),
    mWriteColorSets(iArgs.writeColorSets),
    mWriteUVSets(iArgs.writeUVSets),
    mIsGeometryAnimated(false),
    mDagPath(iDag)
{
    MStatus status = MS::kSuccess;
    MFnMesh lMesh( mDagPath, &status );
    if ( !status )
    {
        MGlobal::displayError( "MFnMesh() failed for MayaMeshWriter" );
    }

    // intermediate objects aren't translated
    MObject surface = iDag.node();

    if (iTimeIndex != 0 && util::isAnimated(surface))
    {
        mIsGeometryAnimated = true;
    }
    else
    {
        iTimeIndex = 0;
    }

    std::vector<float> uvs;
    std::vector<Alembic::Util::uint32_t> indices;
    std::string uvSetName;

    MString name = lMesh.name();
    name = util::stripNamespaces(name, iArgs.stripNamespace);

    // check to see if this poly has been tagged as a SubD
    MPlug plug = lMesh.findPlug("SubDivisionMesh");
    if ( !plug.isNull() && plug.asBool() )
    {
        Alembic::AbcGeom::OSubD obj(iParent, name.asChar(), iTimeIndex);
        mSubDSchema = obj.getSchema();

        Alembic::AbcGeom::OV2fGeomParam::Sample uvSamp;
        if (mWriteUVs || mWriteUVSets)
        {
            getUVs(uvs, indices, uvSetName);

            if (!uvs.empty())
            {
                if (!uvSetName.empty())
                {
                    mSubDSchema.setUVSourceName(uvSetName);
                }

                uvSamp.setScope( Alembic::AbcGeom::kFacevaryingScope );
                uvSamp.setVals(Alembic::AbcGeom::V2fArraySample(
                    (const Imath::V2f *) &uvs.front(), uvs.size() / 2));
                if (!indices.empty())
                {
                    uvSamp.setIndices(Alembic::Abc::UInt32ArraySample(
                        &indices.front(), indices.size()));
                }
            }
        }

        Alembic::Abc::OCompoundProperty cp;
        Alembic::Abc::OCompoundProperty up;
        if (AttributesWriter::hasAnyAttr(lMesh, iArgs))
        {
            cp = mSubDSchema.getArbGeomParams();
            up = mSubDSchema.getUserProperties();
        }
        mAttrs = AttributesWriterPtr(new AttributesWriter(cp, up, obj, lMesh,
            iTimeIndex, iArgs));

        writeSubD(uvSamp);
    }
    else
    {
        Alembic::AbcGeom::OPolyMesh obj(iParent, name.asChar(), iTimeIndex);
        mPolySchema = obj.getSchema();

        Alembic::AbcGeom::OV2fGeomParam::Sample uvSamp;

        if (mWriteUVs || mWriteUVSets)
        {
            getUVs(uvs, indices, uvSetName);

            if (!uvs.empty())
            {
                if (!uvSetName.empty())
                {
                    mPolySchema.setUVSourceName(uvSetName);
                }
                uvSamp.setScope( Alembic::AbcGeom::kFacevaryingScope );
                uvSamp.setVals(Alembic::AbcGeom::V2fArraySample(
                    (const Imath::V2f *) &uvs.front(), uvs.size() / 2));
                if (!indices.empty())
                {
                    uvSamp.setIndices(Alembic::Abc::UInt32ArraySample(
                        &indices.front(), indices.size()));
                }
            }
        }

        Alembic::Abc::OCompoundProperty cp;
        Alembic::Abc::OCompoundProperty up;
        if (AttributesWriter::hasAnyAttr(lMesh, iArgs))
        {
            cp = mPolySchema.getArbGeomParams();
            up = mPolySchema.getUserProperties();
        }

        // set the rest of the props and write to the writer node
        mAttrs = AttributesWriterPtr(new AttributesWriter(cp, up, obj, lMesh,
            iTimeIndex, iArgs));

        writePoly(uvSamp);
    }

    if (mWriteColorSets)
    {
        MStringArray colorSetNames;
        lMesh.getColorSetNames(colorSetNames);

        if (colorSetNames.length() > 0)
        {

            // Create the color sets compound prop
            Alembic::Abc::OCompoundProperty arbParams;
            if (mPolySchema.valid())
            {
                arbParams =  mPolySchema.getArbGeomParams();
            }
            else
            {
                arbParams =  mSubDSchema.getArbGeomParams();
            }

            std::string currentColorSet = lMesh.currentColorSetName().asChar();
            for (unsigned int i=0; i < colorSetNames.length(); ++i)
            {
                // Create an array property for each color set
                std::string colorSetPropName = colorSetNames[i].asChar();

                Alembic::AbcCoreAbstract::MetaData md;
                if (currentColorSet == colorSetPropName)
                {
                    md.set("mayaColorSet", "1");
                }
                else
                {
                    md.set("mayaColorSet", "0");
                }

                if (lMesh.getColorRepresentation(colorSetNames[i]) ==
                    MFnMesh::kRGB)
                {
                    Alembic::AbcGeom::OC3fGeomParam colorProp(arbParams,
                        colorSetPropName, true,
                        Alembic::AbcGeom::kFacevaryingScope, 1, iTimeIndex, md);
                    mRGBParams.push_back(colorProp);
                }
                else
                {
                    Alembic::AbcGeom::OC4fGeomParam colorProp(arbParams,
                        colorSetPropName, true,
                        Alembic::AbcGeom::kFacevaryingScope, 1, iTimeIndex, md);
                    mRGBAParams.push_back(colorProp);
                }
            }
            writeColor();
        }
    }

    if (mWriteUVSets)
    {
        MStringArray uvSetNames;
        lMesh.getUVSetNames(uvSetNames);
        unsigned int uvSetNamesLen = uvSetNames.length();

        if (uvSetNamesLen > 1)
        {
            // Create the uv sets compound prop
            Alembic::Abc::OCompoundProperty arbParams;
            if (mPolySchema.valid())
            {
                arbParams =  mPolySchema.getArbGeomParams();
            }
            else
            {
                arbParams =  mSubDSchema.getArbGeomParams();
            }

            MString currentUV = lMesh.currentUVSetName();

            for (unsigned int i = 0; i < uvSetNamesLen; ++i)
            {
                // Create an array property for each uv set
                MString uvSetPropName = uvSetNames[i];

                // the current UV set gets mapped to the primary UVs
                if (currentUV == uvSetPropName)
                {
                    continue;
                }

                if (uvSetPropName.length() > 0 &&
                    lMesh.numUVs(uvSetPropName) > 0)
                {
                    mUVparams.push_back(Alembic::AbcGeom::OV2fGeomParam(
                        arbParams, uvSetPropName.asChar(), true,
                        Alembic::AbcGeom::kFacevaryingScope, 1, iTimeIndex));
                }
            }
            writeUVSets();
        }
    }

    // write out facesets
    if(!iArgs.writeFaceSets)
        return;

    // get the connected shading engines
    MObjectArray connSGObjs (getOutConnectedSG(mDagPath));
    const unsigned int sgCount = connSGObjs.length();

    for (unsigned int i = 0; i < sgCount; ++i)
    {
        MObject connSGObj, compObj;

        connSGObj = connSGObjs[i];

        MFnDependencyNode fnDepNode(connSGObj);
        MString connSgObjName = fnDepNode.name();

        // retrive the component MObject
        status = getSetComponents(mDagPath, connSGObj, gmMap, compObj);

        if (status != MS::kSuccess)
        {
            // for some reason the shading group doesn't represent a face set
            continue;
        }

        // retrieve the face indices
        MIntArray indices;
        MFnSingleIndexedComponent compFn;
        compFn.setObject(compObj);
        compFn.getElements(indices);
        const unsigned int numData = indices.length();

        // encountered the whole object mapping. skip it.
        if (numData == 0)
            continue;

        std::vector<Alembic::Util::int32_t> faceIndices(numData);
        for (unsigned int j = 0; j < numData; ++j)
        {
            faceIndices[j] = indices[j];
        }

        connSgObjName = util::stripNamespaces(connSgObjName,
                                              iArgs.stripNamespace);

        Alembic::AbcGeom::OFaceSet faceSet;
        std::string faceSetName(connSgObjName.asChar());

        MPlug abcFacesetNamePlug = fnDepNode.findPlug("AbcFacesetName", true);
        if (!abcFacesetNamePlug.isNull())
        {
            faceSetName = abcFacesetNamePlug.asString().asChar();
        }

        if (mPolySchema.valid())
        {
            if (mPolySchema.hasFaceSet(faceSetName))
            {
                faceSet = mPolySchema.getFaceSet(faceSetName);
            }
            else
            {
                faceSet = mPolySchema.createFaceSet(faceSetName);
            }
        }
        else
        {
            if (mSubDSchema.hasFaceSet(faceSetName))
            {
                faceSet = mSubDSchema.getFaceSet(faceSetName);
            }
            else
            {
                faceSet = mSubDSchema.createFaceSet(faceSetName);
            }
        }
        Alembic::AbcGeom::OFaceSetSchema::Sample samp;
        samp.setFaces(Alembic::Abc::Int32ArraySample(faceIndices));

        Alembic::AbcGeom::OFaceSetSchema faceSetSchema = faceSet.getSchema();

        faceSetSchema.set(samp);
        faceSetSchema.setFaceExclusivity(Alembic::AbcGeom::kFaceSetExclusive);

        MFnDependencyNode iNode(connSGObj);

        Alembic::Abc::OCompoundProperty cp;
        Alembic::Abc::OCompoundProperty up;
        if (AttributesWriter::hasAnyAttr(iNode, iArgs))
        {
            cp = faceSetSchema.getArbGeomParams();
            up = faceSetSchema.getUserProperties();
        }

        AttributesWriter attrWriter(cp, up, faceSet, iNode, iTimeIndex, iArgs);
        attrWriter.write();
    }
}
예제 #4
0
파일: alembic.cpp 프로젝트: tsks/mmdbridge
static void export_alembic_xform_by_material_direct(AlembicArchive &archive, const RenderedBuffer & renderedBuffer, int renderedBufferIndex)
{
	Alembic::AbcGeom::OObject topObj(*archive.archive, Alembic::AbcGeom::kTop);

	for (int k = 0, ksize = static_cast<int>(renderedBuffer.materials.size()); k < ksize; ++k)
	{
		Alembic::AbcGeom::OPolyMesh polyMesh;
		const int key = renderedBufferIndex * 10000 + k;
				
		Alembic::AbcGeom::OXform xform;
		if (archive.xform_map.find(key) != archive.xform_map.end())
		{
			xform = archive.xform_map[key];
		}
		else
		{
			xform = Alembic::AbcGeom::OXform(topObj, "xform_" + to_string(renderedBufferIndex) + "_material_" + to_string(k) , archive.timesampling);
			archive.xform_map[key] = xform;
		}

		bool isFirstMesh = false;
		if (archive.mesh_map.find(key) != archive.mesh_map.end())
		{
			polyMesh = archive.mesh_map[key];
		}
		else
		{
			polyMesh = Alembic::AbcGeom::OPolyMesh(xform, "mesh_" + to_string(renderedBufferIndex) + "_material_" + to_string(k), archive.timesampling);
			archive.mesh_map[key] = polyMesh;
			isFirstMesh = true;

			Alembic::AbcGeom::OPolyMeshSchema &meshSchema = polyMesh.getSchema();
			archive.schema_map[key] = meshSchema;
		}

		if (archive.surface_size_map.find(key) == archive.surface_size_map.end())
		{
			archive.surface_size_map[key] = 0;
		}
			
		Alembic::AbcGeom::OPolyMeshSchema &meshSchema = archive.schema_map[key];
		meshSchema.setTimeSampling(archive.timesampling);

		Alembic::AbcGeom::OPolyMeshSchema::Sample empty;
			
		std::vector<Alembic::Util::int32_t> faceList;
		std::vector<Alembic::Util::int32_t> faceCountList;

		const RenderedBuffer::UVList &uvList = renderedBuffer.uvs;
		const RenderedBuffer::VertexList &vertexList = renderedBuffer.vertecies;
		const RenderedBuffer::NormalList &normalList =  renderedBuffer.normals;

		RenderedBuffer::VertexList vertexListByMaterial;
		RenderedBuffer::UVList uvListByMaterial;
		RenderedBuffer::NormalList normalListByMaterial;

		RenderedMaterial* material = renderedBuffer.materials.at(k);
		const int materialSurfaceSize = static_cast<int>(material->surface.faces.size());
		vertexListByMaterial.resize(materialSurfaceSize * 3);
		faceList.resize(materialSurfaceSize * 3);
		faceCountList.resize(materialSurfaceSize);

		if (!uvList.empty())
		{
			uvListByMaterial.resize(materialSurfaceSize * 3);
		}
		if (!normalList.empty())
		{
			normalListByMaterial.resize(materialSurfaceSize * 3);
		}
			
		int& preSurfaceSize = archive.surface_size_map[key];
		bool isFirstSurface = material->surface.faces.size() != preSurfaceSize;
		if (!isFirstMesh && isFirstSurface)
		{
			continue;
		}

		// re assign par material
		int lastIndex = 0;

		for (int n = 0; n < materialSurfaceSize; ++n)
		{
			UMVec3i face = material->surface.faces[n];

			const int f1 = face.x - 1;
			const int f2 = face.y - 1;
			const int f3 = face.z - 1;
			int vi1 = n * 3 + 0;
			int vi2 = n * 3 + 1;
			int vi3 = n * 3 + 2;

			vertexListByMaterial[vi1] = vertexList.at(f1);
			vertexListByMaterial[vi2] = vertexList.at(f2);
			vertexListByMaterial[vi3] = vertexList.at(f3);
			if (!uvList.empty() && archive.is_export_uvs)
			{
				uvListByMaterial[vi1] = uvList.at(f1);
				uvListByMaterial[vi2] = uvList.at(f2);
				uvListByMaterial[vi3] = uvList.at(f3);
			}
			if (!normalList.empty() && archive.is_export_normals)
			{
				normalListByMaterial[vi1] = normalList.at(f1);
				normalListByMaterial[vi2] = normalList.at(f2);
				normalListByMaterial[vi3] = normalList.at(f3);
			}
			faceList[vi1] = vi1;
			faceList[vi2] = vi2;
			faceList[vi3] = vi3;
			faceCountList[n] = 3;
		}

		preSurfaceSize = material->surface.faces.size();
				
		for (int n = 0, nsize = vertexListByMaterial.size(); n < nsize; ++n)
		{
			vertexListByMaterial[n].z = -vertexListByMaterial[n].z;
		}

		Alembic::AbcGeom::OPolyMeshSchema::Sample sample;
				
		// vertex
		Alembic::AbcGeom::P3fArraySample positions( (const Imath::V3f *) &vertexListByMaterial.front(), vertexListByMaterial.size());
		sample.setPositions(positions);
				
		// face index
		if (isFirstMesh)
		{
			Alembic::Abc::Int32ArraySample faceIndices(faceList);
			Alembic::Abc::Int32ArraySample faceCounts(faceCountList);
			sample.setFaceIndices(faceIndices);
			sample.setFaceCounts(faceCounts);
		}

		// UVs
		if (!uvListByMaterial.empty() && archive.is_export_uvs)
		{
			for (int n = 0, nsize = uvListByMaterial.size(); n < nsize; ++n)
			{
				uvListByMaterial[n].y = 1.0f - uvListByMaterial[n].y;
			}
			Alembic::AbcGeom::OV2fGeomParam::Sample uvSample;
			uvSample.setScope(Alembic::AbcGeom::kVertexScope );
			uvSample.setVals(Alembic::AbcGeom::V2fArraySample( ( const Imath::V2f *) &uvListByMaterial.front(), uvListByMaterial.size()));
			sample.setUVs(uvSample);
		}

		// Normals
		if (!normalListByMaterial.empty() && archive.is_export_normals)
		{
			for (int n = 0, nsize = normalListByMaterial.size(); n < nsize; ++n)
			{
				normalListByMaterial[n].z = -normalListByMaterial[n].z;
			}
			Alembic::AbcGeom::ON3fGeomParam::Sample normalSample;
			normalSample.setScope(Alembic::AbcGeom::kVertexScope );
			normalSample.setVals(Alembic::AbcGeom::N3fArraySample( (const Alembic::AbcGeom::N3f *) &normalListByMaterial.front(), normalListByMaterial.size()));
			sample.setNormals(normalSample);
		}
			
		meshSchema.set(sample);
	}
}