1 /*
2     Copyright (c) 2008-2009 NetAllied Systems GmbH
3 
4 	This file is part of COLLADAMaya.
5 
6     Portions of the code are:
7     Copyright (c) 2005-2007 Feeling Software Inc.
8     Copyright (c) 2005-2007 Sony Computer Entertainment America
9     Copyright (c) 2004-2005 Alias Systems Corp.
10 
11     Licensed under the MIT Open Source License,
12     for details please see LICENSE file or the website
13     http://www.opensource.org/licenses/mit-license.php
14 */
15 #ifndef __COLLADA_MAYA_GEOMETRY_POLYGON_EXPORTER_H__
16 #define __COLLADA_MAYA_GEOMETRY_POLYGON_EXPORTER_H__
17 
18 #include "COLLADAMayaStableHeaders.h"
19 #include "COLLADAMayaDocumentExporter.h"
20 #include "COLLADAMayaSceneElement.h"
21 #include "COLLADAMayaGeometryExporter.h"
22 #include "COLLADAMayaPolygonSource.h"
23 #include <vector>
24 
25 #include <maya/MFnMesh.h>
26 #include <maya/MDagPath.h>
27 #include <maya/MItMeshPolygon.h>
28 #include <maya/MVector.h>
29 #include <maya/MItMeshPolygon.h>
30 
31 #include "COLLADASWStreamWriter.h"
32 #include "COLLADASWElementWriter.h"
33 #include "COLLADASWLibraryGeometries.h"
34 #include "COLLADASWInputList.h"
35 #include "COLLADASWPrimitves.h"
36 
37 class DocumentExporter;
38 class ElementWriter;
39 
40 
41 namespace COLLADAMaya
42 {
43 
44 
45     /************************************************************************/
46     /* This class writes the <polylist> elements in the <library_geometries>.                                                                     */
47     /************************************************************************/
48 
49     class GeometryPolygonExporter : public COLLADASW::LibraryGeometries
50     {
51 
52     private:
53 
54         /** The unique id of the mesh object */
55         String mMeshId;
56 
57         /** The array with the uvs */
58         MStringArray mUvSetNames;
59 
60         /** Flag, if face vertex normals exist */
61         bool mHasFaceVertexNormals;
62 
63         /** The shaders of the current mesh. */
64         MObjectArray mShaders;
65 
66         /** The shader indices of the current mesh. */
67         MIntArray mShaderIndices;
68 
69         /** The position of the current shader. */
70         uint mShaderPosition;
71 
72         /** The list with the color sets */
73         MStringArray mColorSetNames;
74 
75         /** true, if triangles should be exported. */
76         bool triangulated;
77 
78         /** Number of holes in the current mesh */
79         uint holeCount;
80 
81         /**
82         * Array of integer triples, one for each hole in the mesh.
83         * The first element in each triple represents the index of the holed face.
84         * The next two elements represent the number of vertexes in the hole and the
85         * hole's start index in list of hole vertexes in holeVertexArray, respectively.
86         * For example, if holeInfoArray = [ 0, 3, 0, 1, 4, 3 ], then this means that
87         * face 0 contains a 3-vertex hole whose vertex indices are stored in elements
88         * 0, 1, 2 of holeVertexArray, and face 1 contains a 4-vertex hole whose vertex
89         * indices are stored in elements 3, 4, 5, 6 of holeVertexArray.
90         */
91         MIntArray mHoleInfoArray;
92 
93         /**
94         * An array consisting of the vertex indices of every hole in the mesh.
95         * The third element of each triple in holeInfoArray is the index of the
96         * start of a particular hole's vertex list in this array.
97         */
98         MIntArray mHoleVertexArray;
99 
100         /** Pointer to the document exporter */
101         DocumentExporter* mDocumentExporter;
102 
103         /** A pointer to the geometry sources input list, which is filled from geometry exporter. */
104         Sources* mPolygonSources;
105 
106         /** A pointer to the vertexes list, which is filled from geometry exporter. */
107         Sources* mVertexSources;
108 
109         /** Vector with the indices of faces which are holes. */
110         std::vector<uint> mHoleFaces;
111 
112 
113     public:
114 
115         /* @param streamWriter The stream the output will be written to                                                                     */
116         GeometryPolygonExporter ( COLLADASW::StreamWriter* _streamWriter,
117                                   DocumentExporter* _documentExporter );
118         virtual ~GeometryPolygonExporter ( void );
119 
120         /**
121         * Exports the data of all polygons from the shaders in the mesh.
122         */
123         void exportPolygonSources (
124             const MObject& mesh,
125             const String& meshId,
126             MStringArray& uvSetNames,
127             MStringArray& colorSetNames,
128             Sources* geometrySourcesList,
129             Sources* vertexes,
130             const bool hasFaceVertexNorms );
131 
132     private:
133 
134         /**
135         * Exports the data of all polygons of the current shader.
136         * @param fnMesh The current mesh object.
137         */
138         void exportShaderPolygons(const MObject& mesh);
139 
140         /**
141          * Verify the polygons of the meshes shader for holes.
142          * @param fnMesh The current mesh object.
143          * @return bool True, if the shader has a holed polygon.
144          */
145         bool verifyPolygonsForHoles(const MObject& mesh);
146 
147         /**
148          * Prepares the polylist in the collada file to add the list values.
149          * @param fnMesh The current mesh object.
150          * @param numPolygons Number of polygons.
151          * @param currentShapeIsHoled True, if we have to implement a polygon instead of a polylist element.
152          * @return COLLADASW::PrimitivesBase* Pointer to the created Template object.
153          */
154         COLLADASW::PrimitivesBase* preparePrimitivesBase(
155             const MObject& mesh,
156             const uint numPolygons,
157             const uint currentShapeIsHoled );
158 
159         /**
160          * Retrieve the shader polygon vertices and write them directly into the collada file.
161          * @param primitivesBasePoly The collada object to export.
162          * @param exportType The type of the polygon source.
163          */
164         void writeShaderPolygons(
165             COLLADASW::PrimitivesBase* primitivesBasePoly,
166             const uint baseExportType,
167             const MObject& mesh);
168 
169         /**
170          * Retrieve the vertex indices and establish the number of polygons (in case of
171          * triangulation more than one is possible) and the number of vertexes in the polygon.
172          * @param fnMesh The mesh object.
173          * @param meshPolygonsIter Iterator of the mesh's polygons.
174          * @param polygon The collada source to hold the polygon data.
175          * @param vertexIndices List of the vertex indices of the current polygon.
176          * @param numPolygons Number of polygons in the current mesh.
177          * @param numVertices Number of vertices in the current mesh.
178          */
179         void initializePolygonSource(
180             const MObject& mesh,
181             MItMeshPolygon &meshPolygonsIter,
182             PolygonSource &polygon,
183             MIntArray &vertexIndices,
184             uint &numPolygons,
185             uint &numVertices );
186 
187         /**
188          * Writes the vertex indices into the collada file.
189          * @param primitivesBasePoly The collada file element (polylist, polygons or triangles).
190          * @param polygon Data of the current polygon (for the face vertices).
191          * @param fnMesh The current mesh object.
192          * @param meshPolygonsIter Iterator of the mesh's polygons.
193          * @param baseExportType The type of the primitivesBasePoly.
194          * @param vertexIndices List of the vertex indices of the current polygon.
195          * @param numPolygons Number of polygons in the current mesh.
196          * @param numVertices Number of vertices in the current mesh.
197          */
198         void writeElementVertexIndices(
199             COLLADASW::PrimitivesBase* primitivesBasePoly,
200             PolygonSource* polygon,
201             const MObject& mesh,
202             MItMeshPolygon &meshPolygonsIter,
203             const uint baseExportType,
204             const MIntArray &vertexIndices,
205             const uint numPolygons,
206             const uint numVertices );
207 
208         /**
209          * Determines the export type of the current primitives base.
210          * @param isHoledShape True, if the current shape is holed.
211          * @return uint The export Type (polylist, polygons or triangles)
212          */
213         uint determinePrimitivesBaseExportType ( const bool isHoledShape );
214 
215         /**
216          * If we should export a polylist and all polygons of the current mesh
217          * are triangles, we will export triangles instead of polygons!
218          * @param fnMesh The current mesh object.
219          * @return bool True, if all polygons in the mesh are triangles.
220          */
221         bool verifyTriangulation(const MObject& mesh);
222 
223         /**
224         * Create the real Polylist/Polygons/Triangles element.
225         */
226         COLLADASW::PrimitivesBase* createPrimitivesBase ( const uint baseExportType );
227 
228         /**
229         * Check if the current face is a normal polygon or a hole and open the corresponding tag.
230         */
231         void openPolygonOrHoleElement ( COLLADASW::PrimitivesBase* polylist,
232                                         PolygonSource* poly,
233                                         const uint currentFaceIndex );
234 
235         /**
236         * Check if the current face is a normal polygon or a hole.
237         */
238         bool checkForHole ( const PolygonSource* polygon, const uint currentFaceIndex );
239 
240         /**
241         * Retrieve the vertex indices and establish the number of polygons (in case of
242         * triangulation more than one is possible) and the number of vertexes in the polygon.
243         */
244         void retrieveVertexIndices (
245             MIntArray &vertexIndices,
246             MItMeshPolygon &meshPolygonsIter,
247             uint &numPolygons,
248             uint &numVertices );
249 
250         /**
251          * Determines the vertex indices and writes them into the collada file.
252          * @param primitivesBasePoly The collada element to write the vertex indices.
253          * @param polygon The polygon with the face vertex data.
254          * @param vertexIndex The list of the vertex indices.
255          * @param normalIndices The normal indices.
256          * @param iteratorVertexIndex The current vertex index.
257          * @param meshPolygonsIter The current mesh polygon to write.
258          * @param fnMesh The current mesh object.
259          * @param polyIndex The current polygon index.
260          */
261         void writeVertexIndices(
262             COLLADASW::PrimitivesBase* primitivesBasePoly,
263             PolygonSource *polygon,
264             const int vertexIndex,
265             const MIntArray &normalIndices,
266             const int iteratorVertexIndex,
267             MItMeshPolygon &meshPolygonsIter,
268             const MObject& mesh,
269             const int polyIndex );
270 
271         /**
272          * Handles the data of a holed polygon element.
273          * @param polygon The polygon to hold the data.
274          * @param polyIndex Index of the current polygon.
275          * @param vertexIndex Index of the current vertex.
276          * @param numVertices Number of vertices in the polygon.
277          * @param iteratorVertexIndex Vertex iterator index.
278          */
279         void handleHoledPolygon(
280             PolygonSource &polygon,
281             int polyIndex,
282             int vertexIndex,
283             int numVertices,
284             int iteratorVertexIndex );
285 
286         /*
287         * Generate the list of the polygon set inputs.
288         */
289         void getPolygonInputAttributes ( COLLADASW::InputList& inputList );
290 
291         /** Retrieve the list of vertex attributes.
292             That's the input list of vertexes in the collada document. */
293         void getVerticesInputAttributes( Sources& vertexAttributes );
294 
295         /** Adds a new hole identifier.
296         The face-vertex count entry should already exist and the identifier will be place
297         in increasing order within the current list of entries within the face-vertex count list.
298         @param index The index of the hole within the face-vertex count list. */
299         void addHole ( uint index );
300 
301         /**
302          * Retrieves the number of polygons and the vertex count list to export.
303          * @param primitivesBase The collada element to write.
304          * @param fnMesh The mesh object.
305          */
306         void writeVertexCountList(
307             COLLADASW::PrimitivesBase* primitivesBase,
308             const MObject& mesh);
309 
310         /**
311          * Counts the number of polygons in the current shape.
312          * @param fnMesh The mesh object.
313          * @return uint Number of polygons in the current shape.
314          */
315         uint getShaderPolygonsCount(const MObject& mesh);
316 
317         /**
318          * Establish the number of vertexes in the polygon.
319          * @param meshPolygonsIter The current shapes mesh polygons itertator.
320          * @param numVertices The current vertex count.
321          * return True, if the vertex count should be added to the list.
322          */
323         bool getPolygonVertexCount(
324             MItMeshPolygon& meshPolygonsIter,
325             unsigned long& numVertices );
326     };
327 }
328 
329 #endif //__COLLADA_MAYA_GEOMETRY_POLYGON_EXPORTER_H__
330