aboutsummaryrefslogtreecommitdiff
path: root/mayaPlug/shaveObjExporter.h
diff options
context:
space:
mode:
Diffstat (limited to 'mayaPlug/shaveObjExporter.h')
-rw-r--r--mayaPlug/shaveObjExporter.h260
1 files changed, 260 insertions, 0 deletions
diff --git a/mayaPlug/shaveObjExporter.h b/mayaPlug/shaveObjExporter.h
new file mode 100644
index 0000000..2beb721
--- /dev/null
+++ b/mayaPlug/shaveObjExporter.h
@@ -0,0 +1,260 @@
+#ifndef _SHAVEOBJEXPORTER_H_
+#define _SHAVEOBJEXPORTER_H_
+
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+#include <maya/MDagPath.h>
+#include <maya/MDagPathArray.h>
+#include <maya/MFnMesh.h>
+#include <maya/MFnNurbsCurve.h>
+#include <maya/MFnNurbsSurface.h>
+#include <maya/MGlobal.h>
+#include <maya/MIntArray.h>
+#include <maya/MItDag.h>
+#include <maya/MItMeshEdge.h>
+#include <maya/MItMeshPolygon.h>
+#include <maya/MItMeshVertex.h>
+#include <maya/MItSelectionList.h>
+#include <maya/MPointArray.h>
+#include <maya/MSelectionList.h>
+
+// We used to use MDagPaths to initialize function sets to access
+// the input surfacs. That was always dangerous given that this
+// code gets called during shaveHairShape::compute(). In Maya 8.0
+// that started to cause problems when it turned out that polygon
+// smooth proxy meshes were not in an internally consistent state
+// in the middle of a compute(): they could have verts but not yet
+// any faces.
+//
+// Here we get around this by pulling the geometry from the mesh's
+// plug to ensure that it updates correctly. The proper approach
+// GET_GEOM_FROM_DATABLOCK represents the correct approach which is to
+// avoid the MDagPaths altogether and get all input geometry from the
+// compute's datablock.
+//
+// Unfortunately that's not finished yet (shaveTextureStore still uses
+// the DAG paths for the surfaces) so GET_GEOM_FROM_PLUGS represents a
+// temporary workaround in which we continue to use MDagPaths to access
+// the nodes, but make sure to pull the geometry from the node's plugs
+// beforehand to ensure that it is up to date.
+//
+// Since the old approach worked prior to Maya 8.0, I'm only enabling this
+// new stuff in 8.0.
+#define GET_GEOM_FROM_DATABLOCK 0
+#define GET_GEOM_FROM_PLUGS 1
+
+#if MAYA_API_VERSION < 20180000
+class MDataBlock;
+class MFloatPointArray;
+#endif
+
+
+typedef struct
+{
+ WFTYPE* theObj;
+ WFTYPE* uvs;
+ MDagPathArray meshes; // The exported meshes, in the order exported
+ MIntArray startFaces; // Face ID of first face of each mesh
+ MIntArray startVerts; // Vertex ID of first vert of each mesh
+ bool newtopo;
+
+ int uSubdivs;
+ int vSubdivs;
+ int lastUSubdiv;
+ int lastVSubdiv;
+
+ int subdDepth;
+ int subdSamples;
+ int lastSubdDepth;
+ int lastSubdSamples;
+
+ MObject shaveHairShape;
+ MString objFileName;
+}ShaveExportData;
+
+
+class shaveObjTranslator {
+public:
+ shaveObjTranslator ();
+ virtual ~shaveObjTranslator (){}
+ static void* creator();
+
+ // called from shaveHairShape in order to export .obj file for the
+ // current node.
+ MStatus exportThis(MDataBlock& block, ShaveExportData& data);
+ MStatus exportOcclusion(MDagPathArray&, WFTYPE *);
+ void exportInstanceObj(MObject instanceMesh, MObject shader, MString filename);
+
+private:
+ enum GeomType {
+ kGrowthGeom,
+ kCollisionGeom,
+ kOcclusionGeom
+ };
+
+ bool newtopo;
+
+#if GET_GEOM_FROM_DATABLOCK
+ MObjectArray hairObjects;
+ MObjectArray hairComponents;
+ MObjectArray fullHairObjects;
+ MObjectArray partialHairObjects;
+ MObjectArray partialHairComponents;
+
+ MObjectArray skullObjects;
+ MObjectArray skullComponents;
+ MObjectArray fullSkullObjects;
+ MObjectArray partialSkullObjects;
+ MObjectArray partialSkullComponents;
+
+#else
+ MSelectionList hairSelections;
+ MSelectionList skullSelections;
+
+ MDagPathArray fullHairObjects;
+ MSelectionList partialHairObjects;
+
+ MDagPathArray fullSkullObjects;
+ MSelectionList partialSkullObjects;
+#endif
+
+ //! the total number of verts we'll write to the WFType.
+ int totalverts;
+ //! the total number of faces we'll write to the WFType.
+ int totalfaces;
+ //! the total number of fverts we'll write to the WFType.
+ int totalfverts;
+
+ MSpace::Space space;
+
+ MStatus objListInit();
+
+ MStatus separateOutPartialMeshes(
+#if GET_GEOM_FROM_DATABLOCK
+ MObjectArray& objects,
+ MObjectArray& components,
+ MObjectArray& fullObjects,
+ MObjectArray& partialMeshes,
+ MObjectArray& partialMeshComponents
+#else
+ MSelectionList& objectList,
+ MDagPathArray& fullObjects,
+ MSelectionList& partialMeshes
+#endif
+ );
+
+ MStatus mtlLookupInit(bool**& growthFaces, bool**& collisionFaces);
+ void mtlLookupCleanup(bool**& growthFaces, bool**& collisionFaces);
+
+ MStatus createMtlLookup(MSelectionList& objectList, bool**& lookupTbl);
+ void deleteMtlLookup(MSelectionList& objectList, bool**& lookupTbl);
+
+ void exportFullObjects(
+ FILE* exportFile,
+#if GET_GEOM_FROM_DATABLOCK
+ MObjectArray& objects,
+#else
+ MDagPathArray& objects,
+#endif
+ MObjectArray tesselations,
+ const char* surfaceMaterial,
+ const char* curveMaterial,
+ int& objectIndex,
+ int& vtxOffset,
+ int& faceOffset
+ );
+
+ void exportPartialMeshes(
+ FILE* exportFile,
+#if GET_GEOM_FROM_DATABLOCK
+ MObjectArray& meshList,
+#else
+ MSelectionList& meshList,
+#endif
+ bool** activeFaceMap,
+ const char* activeFaceMaterial,
+ int& objectIndex,
+ int& vertexOffset,
+ int& faceOffset
+ );
+
+ MStatus doExport(
+ MString fileName,
+ MObjectArray tesselations,
+ bool** growthFaces,
+ bool** collisionFaces
+ );
+
+ void storeMeshInWFTYPE(
+ WFTYPE* wf,
+ WFTYPE* uvs,
+ MItMeshVertex& vertexIter,
+ MItMeshPolygon& faceIter,
+ int& vertexIndex,
+ int& faceIndex,
+ int& faceVertexIndex
+ );
+
+ void storeObjectInWFTYPE(
+ WFTYPE* wf,
+ WFTYPE* uvs,
+#if GET_GEOM_FROM_DATABLOCK
+ MObject& object,
+#else
+ MDagPath& object,
+#endif
+ MObject tempMesh,
+ int& vertexIndex,
+ int& faceIndex,
+ int& faceVertexIndex
+ );
+
+ void getObjectCounts(
+#if GET_GEOM_FROM_DATABLOCK
+ MObject& object,
+#else
+ MDagPath& object,
+#endif
+ GeomType geomType,
+ int& numVertices,
+ int& numFaces,
+ int& numFaceVertices,
+ int uTess,
+ int vTess,
+ int sDept,
+ int sSamp,
+ ShaveExportData* exportData,
+ MObjectArray& tesselations,
+ bool includeDisplacements = false
+ );
+
+ MStatus wfInit(
+ int uTess,
+ int vTess,
+ int sDept,
+ int sSamp,
+ ShaveExportData& exportData,
+ MObjectArray& tesselations
+ );
+
+ bool checkExported();
+
+ MStatus doWFType(WFTYPE* wf, WFTYPE* uvs, MObjectArray tesselations);
+
+ MObject getConnectedShader(MFnMesh);
+
+ void getCurveSamples(
+#if GET_GEOM_FROM_DATABLOCK
+ MObject curve, MFloatPointArray& samples
+#else
+ MDagPath curve, MFloatPointArray& samples
+#endif
+ );
+
+ MString getShaderTexture(MObject shadingGroup);
+};
+
+#endif
+