1/****************************************************************************************
2
3 Copyright (C) 2015 Autodesk, Inc.
4 All rights reserved.
5
6 Use of this software is subject to the terms of the Autodesk license agreement
7 provided at the time of installation or download, or which otherwise accompanies
8 this software in either electronic or hard copy form.
9
10****************************************************************************************/
11
12//! \file fbxmesh.h
13#ifndef _FBXSDK_SCENE_GEOMETRY_MESH_H_
14#define _FBXSDK_SCENE_GEOMETRY_MESH_H_
15
16#include <fbxsdk/fbxsdk_def.h>
17
18#include <fbxsdk/core/base/fbxarray.h>
19#include <fbxsdk/scene/geometry/fbxgeometry.h>
20
21#include <fbxsdk/fbxsdk_nsbegin.h>
22
23/** A mesh is a geometry made of polygons.
24* The class can define a geometry with as many n-sided polygons as needed. Users can freely
25* mix triangles, quadrilaterals, and other polygons. Since the mesh-related terminology of the FBX SDK
26* differs a little from the known standards, here are our definitions:
27* \li A control point is an XYZ coordinate, it is synonym of vertex.
28* \li A polygon vertex is an index to a control point (the same control point can be referenced by multiple polygon vertices).
29* \li A polygon is a group of polygon vertices. The minimum valid number of polygon vertices to define a polygon is 3.
30* \nosubgrouping
31* Methods to initialize, set and access control points are provided in the FbxGeometryBase class. */
32class FBXSDK_DLL FbxMesh : public FbxGeometry
33{
34 FBXSDK_OBJECT_DECLARE(FbxMesh, FbxGeometry);
35
36public:
37 /** Return the type of node attribute.
38 * \return Return the type of this node attribute which is \e EType::eMesh. */
39 virtual FbxNodeAttribute::EType GetAttributeType() const;
40
41 /** \name Polygon Management */
42 //@{
43 /** Begins the process of adding a polygon to the mesh.
44 * Add vertexes to the polygon using AddPolygon. When the polygon is complete call EndPolygon to complete the creation of the polygon.
45 * \param pMaterial Index of material to assign to this polygon if material mapping type is \e eByPolygon. Otherwise it must be \c -1.
46 * \param pTexture Index of texture to assign to this polygon if texture mapping type is \e eByPolygon. Otherwise it must be \c -1.
47 * \param pGroup Group index assigned to polygon.
48 * \param pLegacy When set to \c true, automatically create a LayerElement of type Texture; This was the default behavior of earlier
49 * versions of the FBX SDK. Since version 2010, the textures are connected to the material object.
50 * \remark This function must be called before AddPolygon().
51 * \remark If used, the pTexture index will reference textures assigned to the DIFFUSE channel (FbxLayerElement::eTextureDiffuse). */
52 void BeginPolygon(int pMaterial=-1, int pTexture=-1, int pGroup=-1, bool pLegacy=true);
53
54 /** Begin writing a polygon.
55 * Add vertexes to the polygon using AddPolygon. When the polygon is complete call EndPolygon to complete the creation of the polygon.
56 * \param pMaterial Index of material to assign to this polygon if material mapping type is \e eByPolygon. Otherwise it must be \c -1.
57 * \param pTextures Array of index of texture (by texture type) to assign to this polygon if texture mapping type is \e eByPolygon.
58 * Otherwise it must be an array of \c -1. This array is expected to be of size: FbxLayerElement::sTypeTextureCount. If one texture
59 * type is not used, the corresponding entry must be left at \c -1. */
60 void BeginPolygonExt(int pMaterial, int* pTextures);
61
62 /** Add a polygon vertex to the current polygon.
63 * \param pIndex Index in the table of the control points.
64 * \param pTextureUVIndex Index of texture UV coordinates to assign to this polygon if texture UV mapping type is \e eByPolygonVertex. Otherwise it must be \c -1.
65 * \remark After adding all the polygons of the mesh, call function "BuildMeshEdgeArray" to generate edge data for the mesh. */
66 void AddPolygon(int pIndex, int pTextureUVIndex = -1);
67
68 //! End writing a polygon, it should be called after adding one polygon.
69 void EndPolygon();
70
71 /** Get the polygon count of this mesh.
72 * \return Return the number of polygons in the mesh. */
73 inline int GetPolygonCount() const { return mPolygons.GetCount(); }
74
75 /** Get the number of polygon vertices in a polygon.
76 * \param pPolygonIndex Index of the polygon.
77 * \return The number of polygon vertices in the indexed polygon. If the polygon index is out of bounds, return -1. */
78 inline int GetPolygonSize(int pPolygonIndex) const
79 {
80 return ( pPolygonIndex >= 0 && pPolygonIndex < mPolygons.GetCount() ) ? mPolygons[pPolygonIndex].mSize : -1;
81 }
82
83 /** Get the current group ID of the specified polygon.
84 * A polygon group can be useful to identify a number of polygons that share the same properties. The FBX SDK does not use this information internally
85 * but guarantee its persistence in the FBX files and in memory.
86 * \param pPolygonIndex Index of the polygon.
87 * \return Group index assigned to the polygon. If the polygon index is out of bounds, return -1. */
88 int GetPolygonGroup(int pPolygonIndex) const;
89
90 /** Assign the specified polygon a group ID.
91 * A polygon can only be assigned to one group at the time.
92 * \param pPolygonIndex Index of the polygon.
93 * \param pGroup Group index assigned to the polygon.
94 * \return Group index assigned to the polygon. If the polygon index is out of bounds, do nothing. */
95 inline void SetPolygonGroup(int pPolygonIndex, int pGroup) const
96 {
97 if( pPolygonIndex >= 0 && pPolygonIndex<mPolygons.GetCount() ) mPolygons[pPolygonIndex].mGroup = pGroup;
98 }
99
100 /** Get a polygon vertex (i.e: an index to a control point).
101 * \param pPolygonIndex Index of queried polygon. The valid range for this parameter is 0 to \c FbxMesh::GetPolygonCount().
102 * \param pPositionInPolygon Position of polygon vertex in indexed polygon. The valid range for this parameter is 0 to \c FbxMesh::GetPolygonSize(pPolygonIndex).
103 * \return Return the polygon vertex indexed or -1 if the requested vertex does not exists or the indices arguments have an invalid range. */
104 inline int GetPolygonVertex(int pPolygonIndex, int pPositionInPolygon) const
105 {
106 return ( pPolygonIndex >= 0 && pPolygonIndex < mPolygons.GetCount() && pPositionInPolygon >= 0 && pPositionInPolygon < mPolygons[pPolygonIndex].mSize ) ?
107 mPolygonVertices[mPolygons[pPolygonIndex].mIndex + pPositionInPolygon] : -1;
108 }
109
110 /** Get the normal associated with the specified polygon vertex.
111 * \param pPolyIndex Index of the polygon.
112 * \param pVertexIndex Index of the vertex in the polygon.
113 * \param pNormal The returned normal.
114 * \return \c True on success, \c false on failure.
115 * \remark \c pNormal remain unchanged if the requested vertex does not exists. */
116 bool GetPolygonVertexNormal(int pPolyIndex, int pVertexIndex, FbxVector4& pNormal) const;
117
118 /** Get the normals associated with the mesh for every polygon vertex.
119 * \param pNormals The returned normals.
120 * \return \c True on success, \c false on failure. */
121 bool GetPolygonVertexNormals(FbxArray<FbxVector4>& pNormals) const;
122
123 /** Get the UV associated with the specified polygon vertex.
124 * \param pPolyIndex Index of the polygon.
125 * \param pVertexIndex Index of the vertex in the polygon.
126 * \param pUVSetName The name of the UV set that contains the UV.
127 * \param pUV The returned UV.
128 * \param pUnmapped State flag that indicates if the polygon vertex does not have an associated UV.
129 * \return \c True on success, \c false on failure.
130 * \remark \c pUV remain unchanged if the requested vertex does not exists.
131 * \remark This function return \c true if the specified polygon vertex does not have an associated UV. In this case,
132 * pUnampped is set to \c true and the content of \c pUV is undefined.
133 */
134 bool GetPolygonVertexUV(int pPolyIndex, int pVertexIndex, const char* pUVSetName, FbxVector2& pUV, bool& pUnmapped) const;
135
136 /** Get the UVs associated with the mesh for every polygon vertex.
137 * \param pUVSetName The name of the UV set that contains the UVs.
138 * \param pUVs The returned UVs.
139 * \param pUnmappedUVId If specified, this array will be filled with the indices of the UVs that are not associated to a polygon vertex and thus,
140 * have an undefined value. If the array as a size of 0, then all the polygon vertices have an associated UV coordinate and the \c pUVs
141 * array can be used as is. Otherwise, the calling application may be required to process the invalid UV coordinates to avoid inconsistent
142 * results. It is strongly suggested to use the FbxLayerElementUV's Direct and Indexed arrays directly (specially if the calling application
143 * supports indirection of the UVs).
144 * \remark unmapped UV coordinates are set to (0,0)
145 * \return \c True on success, \c false on failure.
146 */
147 bool GetPolygonVertexUVs(const char* pUVSetName, FbxArray<FbxVector2>& pUVs, FbxArray<int>* pUnmappedUVId = NULL) const;
148
149 /** Get the array of polygon vertices (i.e: indices to the control points).
150 * This array is a concatenation of the list of polygon vertices of all the polygons. Example: a mesh made of 2 triangles with vertices [1,2,3]
151 * and vertices [2,3,4] results in [1,2,3,2,3,4]. The first polygon starts at position 0 and the second at position 3.
152 * \return The array of polygon vertices. */
153 int* GetPolygonVertices() const;
154
155 /** Gets the number of polygon vertices in the mesh.
156 * \return The overall size of the array of polygon vertices in the mesh.
157 * \remark This value can be smaller than the value returned by GetControlPointsCount() (meaning that not all of the control points stored in the object are used to define the mesh).
158 * However, typically it will be much bigger since any given control point can be used to define a vertex on multiple polygons. */
159 inline int GetPolygonVertexCount() const { return mPolygonVertices.Size(); }
160
161 /** Gets the start index into the array returned by GetPolygonVertices() for the given polygon.
162 * This method can be used for a faster access to the polygon vertices indices. If, for example, we want to
163 * access the indices for polygon 3, the following code would do the trick
164 * \code
165 * int lStartIndex = mesh.GetPolygonVertexIndex(3);
166 * if( lStartIndex == -1 ) return;
167 * int* lVertices = mesh.GetPolygonVertices()[lStartIndex];
168 * int lCount = mesh.GetPolygonSize(3);
169 * for( int i = 0; i < lCount; ++i )
170 * {
171 * int vertexID = lVertices[i];
172 * ...
173 * }
174 * \endcode
175 * \param pPolygonIndex The polygon of interest.
176 * \return The index into the GetPolygonVertices() array.
177 * \remark If the polygon index is out of bounds, return -1. */
178 int GetPolygonVertexIndex(int pPolygonIndex) const;
179
180 /** Remove the specified polygon from the mesh.
181 * This method will automatically update the layers accordingly.
182 * \param pPolygonIndex Index of the polygon.
183 * \return Polygon index.
184 * \remark If the polygon index is out of bounds, return -1. */
185 int RemovePolygon(int pPolygonIndex);
186
187 /** Remove the duplicated edges from the mesh.
188 * This method will remove duplicated edges. It will not change any vertex and not change the mesh topology.
189 * \param pEdgeIndexList Index list of edges.
190 * \return the count of removed edges.
191 * \remark the edge index list must be ordered. The last one is the max. If the edge index is out of bounds, return -1. */
192 int RemoveDuplicatedEdges(FbxArray<int>& pEdgeIndexList);
193 //@}
194
195 /** \name Texture UV Utility Functions.
196 *
197 * The methods found in this section are utility functions used to handle UV coordinates quickly. Internally, they
198 * refer to \c FbxLayer and \c FbxLayerElementUV methods to do the job. Except for the GetAllChannelUV(int pLayer),
199 * all the methods are implicitly working on Layer 0. Use the \c FbxLayer methods to have access to the other layers. */
200 //@{
201 /** Init texture UV coordinates.
202 * \param pCount Number of texture UV elements.
203 * \param pTypeIdentifier Specifies which texture channel this UV refers to.
204 * \remark \c pCount must equal the number of control points of the Mesh if
205 * the UV mapping mode is \e FbxLayerElement::eByControlPoint. */
206 void InitTextureUV(int pCount, FbxLayerElement::EType pTypeIdentifier=FbxLayerElement::eTextureDiffuse);
207
208 /** Add texture UV coordinates.
209 * Appends a new element at the end of the array of texture UV coordinates.
210 * \param pUV Texture UV coordinates, ranging between \c 0 and \c 1.
211 * \param pTypeIdentifier Specifies which texture channel this UV refers to.
212 * \remark The final number of texture UV elements must equal the number of control
213 * points if the UV mapping mode is \e FbxLayerElement::eByControlPoint. */
214 void AddTextureUV(FbxVector2 pUV, FbxLayerElement::EType pTypeIdentifier=FbxLayerElement::eTextureDiffuse);
215
216 /** Get the number of texture UV coordinates.
217 * \param pTypeIdentifier The texture channel the UV refers to. */
218 int GetTextureUVCount(FbxLayerElement::EType pTypeIdentifier=FbxLayerElement::eTextureDiffuse);
219
220 /** Get the number of layer containing at least one channel UVMap.
221 * return \e 0 if no UV maps have been defined. */
222 int GetUVLayerCount() const;
223
224 /** Fills an array describing, for the given layer, which texture channel have UVs associated to it.
225 * \param pLayer Index of the layer.
226 * \return Array with the channel descriptor.
227 * \remark Only the channels that have UVs associated are reported in the array. For example, let's assume that we have defined UVs for the Diffuse,
228 * Ambient and Bump channels on layer 0. The resulting array will have the following three entries:
229 * \li FbxLayerElement::eDIFFUSE_TEXTURE
230 * \li FbxLayerElement::eAMBIENT_TEXTURE
231 * \li FbxLayerElement::eBUMP_TEXTURE */
232 FbxArray<FbxLayerElement::EType> GetAllChannelUV(int pLayer);
233 //@}
234
235 /** \name Material, Texture and UV Indices Utility Functions.
236 * The methods found in this section are utility functions used to handle Material, Texture and UV indices quickly.
237 * Internally, they refer to \c FbxLayer and \c FbxLayerElementUV methods to do the job. These functions are only
238 * working on Layer 0. Use the \c FbxLayer methods directly to access other layers. */
239 //@{
240 /** Initialize material indices.
241 * \param pMappingMode The mapping mode.
242 * This method must be called after FbxGeometryBase::InitControlPoints().
243 * The material indices refer to the position of a material in the FbxLayerElementMaterial's direct array.
244 * See FbxLayerElementMaterial for more details. Supported mapping types are \e eByControlPoint,
245 * \e eByPolygon and \e eALL_SAME.
246 * - If mapping mode is \e eByControlPoint, there will be as many indices in the material index array
247 * as there are control points.
248 * - If mapping mode is \e eByPolygon, there will be as many indices in the material index array
249 * as there are polygons in the mesh.
250 * - If mapping mode is \e eALL_SAME, there will be only one index in the material index array.
251 * \remark This function will set the Reference mode of the FbxLayerElementMaterial on layer 0 to \e eIndexToDirect. */
252 void InitMaterialIndices(FbxLayerElement::EMappingMode pMappingMode);
253
254 /** Initialize texture indices.
255 * \param pMappingMode The mapping mode.
256 * The texture indices refer to the texture connection to the material. In older versions of the FBX SDK, the
257 * indices were referring to the entries in the direct array of the FbxLayerElementTexture.
258 * See FbxLayerElementTexture for more details. Supported mapping modes are \e eByPolygon
259 * and \e eALL_SAME.
260 * - If mapping mode is \e eByPolygon, there will be as many indices in the texture index array
261 * as there are polygons in the mesh.
262 * - If mapping mode is \e eALL_SAME, there will be only one index in the texture index array.
263 * \param pTextureType The texture channel identifier.
264 * \remark This function will set the Reference mode of the FbxLayerElementTexture on layer 0 to \e eIndexToDirect. */
265 void InitTextureIndices(FbxLayerElement::EMappingMode pMappingMode, FbxLayerElement::EType pTextureType);
266
267 /** Initialize texture UV indices.
268 * \param pMappingMode The mapping mode.
269 * The texture UV indices refer to the index of an element in the FbxLayerElementUV's direct array.
270 * See FbxLayerElementUV for more details. Supported mapping types are \e eByControlPoint , \e eByPolygonVertex
271 * and \e eALL_SAME.
272 * - If mapping mode is \e eByControlPoint, there will be as many indices in the UV index array
273 * as there are control points. This will also set the Reference mode of the FbxLayerElementUV on
274 * layer 0 to \e eDirect.
275 * - If mapping mode is \e eByPolygonVertex, there will be an index in the UV index array
276 * for each vertex, for each polygon it is part of. This will also set the Reference mode of the FbxLayerElementUV on
277 * layer 0 to \e eIndexToDirect.
278 * - If mapping mode is \e eALL_SAME, there will be no index in the UV index array. This will also set the Reference
279 * mode of the FbxLayerElementUV on layer 0 to \e eDirect.
280 * \param pTypeIdentifier The texture channel the UVIndices refers to. */
281 void InitTextureUVIndices(FbxLayerElement::EMappingMode pMappingMode, FbxLayerElement::EType pTypeIdentifier=FbxLayerElement::eTextureDiffuse);
282
283 /** Get a texture UV index associated with a polygon vertex (i.e: an index to a control point).
284 * \param pPolygonIndex Index of polygon.
285 * The valid range for this parameter is 0 to FbxMesh::GetPolygonCount().
286 * \param pPositionInPolygon Position of polygon vertex in indexed polygon.
287 * The valid range for this parameter is 0 to FbxMesh::GetPolygonSize(pPolygonIndex).
288 * \param pTypeIdentifier The texture channel the UVIndex refers to.
289 * \return Return a texture UV index.
290 * \remark This function only works if the texture UV mapping mode is set to \e eByPolygonVertex,
291 * otherwise it returns -1. */
292 int GetTextureUVIndex(int pPolygonIndex, int pPositionInPolygon, FbxLayerElement::EType pTypeIdentifier=FbxLayerElement::eTextureDiffuse);
293
294 /** Set a texture UV index associated with a polygon vertex (i.e: an index to a control point).
295 * \param pPolygonIndex Index of polygon.
296 * The valid range for this parameter is 0 to FbxMesh::GetPolygonCount().
297 * \param pPositionInPolygon Position of polygon vertex in indexed polygon.
298 * The valid range for this parameter is 0 to FbxMesh::GetPolygonSize(pPolygonIndex).
299 * \param pIndex The index of the texture UV we want to assign to the polygon vertex.
300 * \param pTypeIdentifier The texture channel the UVIndex refers to.
301 * \remark This function only works if the texture UV mapping type is set to \e eByPolygonVertex. */
302 void SetTextureUVIndex(int pPolygonIndex, int pPositionInPolygon, int pIndex, FbxLayerElement::EType pTypeIdentifier);
303 //@}
304
305 /** \name Utility functions */
306 //@{
307 /** Reset the mesh to default values.
308 * Frees and set to \c NULL all layers and clear the polygon and the control point array. */
309 void Reset();
310
311 /** Generate vertex normals on the mesh.
312 * The normal computation takes into consideration, as much as possible, the smoothing groups.
313 * \param pOverwrite If true, re-generate normals data regardless of availability, otherwise left untouched if exist.
314 * \param pByCtrlPoint If true, the recomputed normals will be defined by control points instead of by polygon vertex.
315 * \param pCW True if the normals are calculated clockwise, false otherwise (counter-clockwise).
316 * \return \c true if successfully generated normals data, or if already available and pOverwrite is false. */
317 bool GenerateNormals(bool pOverwrite=false, bool pByCtrlPoint = false, bool pCW=false);
318
319 /** Compares the normals calculated by doing cross-products between the polygon vertex and by the ones
320 * stored in the normal array.
321 * \returns \c false if ALL of them are Clockwise. Returns \c true otherwise. */
322 bool CheckIfVertexNormalsCCW();
323
324 //! Internal structure used to keep the duplicate vertex information.
325 class DuplicateVertex
326 {
327 public:
328 DuplicateVertex() :
329 lVertexPolyIndex(0),
330 lNewVertexIndex(0),
331 lNormal(0, 0, 0),
332 lUV(0, 0),
333 lEdgeIndex(0)
334 {
335 }
336
337 int lVertexPolyIndex; //!< Index in mPolygonsVertex where the vertex is found.
338 int lNewVertexIndex; //!< The new index of the vertex.
339 FbxVector4 lNormal; //!< The normal associated with this duplicate control point.
340 FbxVector2 lUV; //!< The UV associated with this duplicate control point.
341 int lEdgeIndex; //!< The edge index.
342 };
343
344 //! Internal structure used to compute the normals on a mesh
345 class VertexNormalInfo
346 {
347 public:
348 VertexNormalInfo() :
349 mTotalNormal(0, 0, 0),
350 mNumNormal(0)
351 {
352 }
353
354 FbxVector4 mTotalNormal; //!< Sum of all the normals found.
355 int mNumNormal; //!< Number of normals added.
356 };
357
358 /** Verify if the mesh has polygons that are defined on the same point more than once.
359 * \return true if the mesh has that kind of polygon, false otherwise. */
360 bool CheckSamePointTwice() const;
361
362 /** Remove bad polygons from a mesh.
363 * Degenerate polygons use a vertex more than once. Remove them from the mesh and
364 * from the layer element indices as needed.
365 * \return Number of polygons removed from the mesh, -1 if an error occurred. */
366 int RemoveBadPolygons();
367 //@}
368
369 /** \name Point Splitting/Merging utility functions */
370 //@{
371 /** Split points.
372 * \param pTypeIdentifier Specify which UVs are processed.
373 * \return \c true if a split occurred, false otherwise.
374 * \remark This method replaces the BuildSplitList and SplitPointsForHardEdge. */
375 bool SplitPoints(FbxLayerElement::EType pTypeIdentifier=FbxLayerElement::eTextureDiffuse);
376
377 /** Insert the new indexes of the object that have to be merged.
378 * \param pMergeList The list that will contain the indexes of the objects to merge.
379 * \param pExport If set to \c true, include the duplicate indexes in the merge list. */
380 bool BuildMergeList(FbxArray<int>& pMergeList, bool pExport=false);
381
382 /** Merge the points specified in the list.
383 * \param pMergeList List containing the information on the points that will be merged. */
384 void MergePointsForPolygonVerteNormals(FbxArray<int> &pMergeList);
385 //@}
386
387 /** \name Edge management functions */
388 //@{
389 /** Automatically generate edge data for the mesh. Clears all previously stored edge information */
390 void BuildMeshEdgeArray();
391
392 /** Query the number of edges defined on this mesh
393 * \return The number of edges defined for this mesh */
394 int GetMeshEdgeCount() const;
395
396 /** Get the index for the edge between the given vertices.
397 * Note that the result of this method is the same if pStartVertexIndex and pEndVertexIndex are swapped.
398 * \param pStartVertexIndex The starting point of the edge.
399 * \param pEndVertexIndex The ending point of the edge.
400 * \param pReversed flag will be set to true if the reverse edge is found, false otherwise.
401 * \param pExistedEdgeCount legal edge count in mEdgeArray
402 * \return -1 if no edge exists for the given pair of vertices. */
403 int GetMeshEdgeIndex(int pStartVertexIndex, int pEndVertexIndex, bool& pReversed, int pExistedEdgeCount=-1);
404
405 /** Use this method before calling GetMeshEdgeIndexForPolygon if making several calls to that method.
406 * Once done calling GetMeshEdgeIndexForPolygon, call EndGetMeshEdgeIndex. This will optimize access time.
407 * Do not modify the mesh between calls to BeginGetMeshEdgeIndex and EndGetMeshEdgeIndex. */
408 void BeginGetMeshEdgeIndexForPolygon();
409
410 /** Use this method after calling GetMeshEdgeIndexForPolygon if making several calls to that method.
411 * This will optimize access time.
412 * Do not modify the mesh between calls to BeginGetMeshEdgeIndex and EndGetMeshEdgeIndex. */
413 void EndGetMeshEdgeIndexForPolygon();
414
415 /** Get the index for the specific edge of pPolygon.
416 * \param pPolygon The polygon of interest.
417 * \param pPositionInPolygon The specific edge number in the polygon.
418 * \return -1 if the specific edge does not exist.
419 * \remark To optimize access time when making several calls to this method, enclose these calls
420 * between the BeginGetMeshEdgeIndexForPolygon() and EndGetMeshEdgeIndexForPolygon() calls. */
421 int GetMeshEdgeIndexForPolygon(int pPolygon, int pPositionInPolygon);
422
423 /** Get the vertices for the given edge. Note that the values returned are indices into the control point array.
424 * \param pEdgeIndex The edge to query.
425 * \param pStartVertexIndex The edge's starting point will be stored here.
426 * \param pEndVertexIndex The edge's starting point will be stored here. */
427 void GetMeshEdgeVertices(int pEdgeIndex, int& pStartVertexIndex, int& pEndVertexIndex) const;
428
429 /** Use this method before calling GetMeshEdgeVertices if making several calls to that method.
430 * Once done calling GetMeshEdgeVertices, call EndGetMeshEdgeVertices. This will optimize access time.
431 * Do not modify the mesh between calls to BeginGetMeshEdgeVertices and EndGetMeshEdgeVertices. */
432 void BeginGetMeshEdgeVertices();
433
434 /** Use this method after calling GetMeshEdgeVertices if making several calls to that method.
435 * This will optimize access time.
436 * Do not modify the mesh between calls to BeginGetMeshEdgeVertices and EndGetMeshEdgeVertices. */
437 void EndGetMeshEdgeVertices();
438
439 /** Presets the number edge data elements.
440 * \param pEdgeCount The number of edges to allocate. */
441 void SetMeshEdgeCount(int pEdgeCount);
442
443 /** Sets element in edge array to specific value.
444 * \param pEdgeIndex The edge index
445 * \param pValue The edge data */
446 inline void SetMeshEdge(int pEdgeIndex, int pValue){ if( pEdgeIndex >= 0 && pEdgeIndex < mEdgeArray.GetCount() ) mEdgeArray[pEdgeIndex] = pValue; }
447
448 /** Add an edge with the given start/end points. Note that the inserted edge
449 * may start at the given end point, and end at the given start point.
450 * \param pStartVertexIndex The starting point of the edge.
451 * \param pEndVertexIndex The ending point of the edge.
452 * \param pCheckForDuplicates Set to true to check if the mesh already contains an edge with these two points.
453 * Can be set to false to speed up this method, when the incoming edges are known to be consistent.
454 * \return Edge index of the new edge, or -1 on failure (edge/reverse edge already exists, no face using these 2 points consecutively ) */
455 int AddMeshEdgeIndex(int pStartVertexIndex, int pEndVertexIndex, bool pCheckForDuplicates);
456
457 /** Set the index for the edge with the given start/end points. Note that the edge
458 * may start at the given end point, and end at the given start point.
459 * \param pEdgeIndex The edge index of the edge.
460 * \param pStartVertexIndex The starting point of the edge.
461 * \param pEndVertexIndex The ending point of the edge.
462 * \param pCheckForDuplicates Set to true to check if the mesh already contains an edge with these two points.
463 * Can be set to false to speed up this method, when the incoming edges are known to be consistent.
464 * \param pExistedEdgeCount the valid edge count that we have created in edge array. This parameter only works when pCheckForDuplicates is true.
465 * The default value is -1 which meaning current edge array has been fully filled with valid edges, i.e.,
466 * we will search the full edge array for the duplicated edge.
467 * \return Edge index of the edge, or -1 on failure (no face using these 2 points consecutively ), or -2 if edge/reverse edge already exists */
468 int SetMeshEdgeIndex(int pEdgeIndex, int pStartVertexIndex, int pEndVertexIndex, bool pCheckForDuplicates, int pExistedEdgeCount=-1);
469
470 /** Call this before calling AddMeshEdgeIndex or SetMeshEdgeIndex to increase performance.
471 * Once finished adding/setting edges EndAddMeshEdgeIndex should be called. */
472 void BeginAddMeshEdgeIndex();
473
474 /** After calling AddMeshEdgeIndex or SetMeshEdgeIndex, EndAddMeshEdgeIndex should be called. */
475 void EndAddMeshEdgeIndex();
476
477 /** Adds an edge for the specified polygon, and edge number within the polygon. See SetMeshEdgeIndex for notes the the parameters.
478 * \param pPolygonIndex The polygon of interest.
479 * \param pPositionInPolygon The edge within the polygon
480 * \return edge index or -1 if failed. */
481 int AddMeshEdgeIndexForPolygon(int pPolygonIndex, int pPositionInPolygon);
482
483 /** Sets the specified edge to the specified polygon's edge.
484 * Note that the position in the polygon ranges from 0 to GetPolygonSize(pPolygonindex) - 1
485 * and represents the edge from GetPolygonVertex(pPolygonIndex, pPositionInPolygon) to
486 * GetPolygonVertex( pPolygonIndex, pPositionInPolygon + 1 ) or from pPositionInPolygon to
487 * 0 if pPositionInPolygon == GetPolygonSize(pPolygonindex) - 1
488 * \param pEdgeIndex The edge.
489 * \param pPolygonIndex The polygon.
490 * \param pPositionInPolygon The specific edge number in the polygon.
491 * \return true on success, false on failure. ( edge for the poly and position already exists ) */
492 bool SetMeshEdgeIndex(int pEdgeIndex, int pPolygonIndex, int pPositionInPolygon);
493
494 /** Determines if the mesh is composed entirely of triangles.
495 * \return true if all polygons are triangles, false otherwise */
496 bool IsTriangleMesh() const;
497 //@}
498
499 /** Reserve memory in the polygon array to hold the specified number of polygons
500 * \param pCount The number of polygons this mesh will hold */
501 inline void ReservePolygonCount(int pCount) { mPolygons.Reserve(pCount); }
502
503 /** Reserve memory in the polygon vertex array to hold the specified number of polygon vertices.
504 * \param pCount The number of polygon vertices */
505 inline void ReservePolygonVertexCount(int pCount) { mPolygonVertices.Reserve(pCount); }
506
507 bool GetTextureUV(FbxLayerElementArrayTemplate<FbxVector2>** pLockableArray, FbxLayerElement::EType pTypeIdentifier=FbxLayerElement::eTextureDiffuse) const;
508 bool GetMaterialIndices(FbxLayerElementArrayTemplate<int>** pLockableArray) const;
509 bool GetTextureIndices(FbxLayerElementArrayTemplate<int>** pLockableArray, FbxLayerElement::EType pTextureType) const;
510
511 /** \name Crease utility functions */
512 //@{
513 /** Get crease weight by edge index.
514 * \param pEdgeIndex Edge index.
515 * \return Crease weight value in the range [0.0 - 1.0]. */
516 double GetEdgeCreaseInfo(int pEdgeIndex);
517
518 /** Get crease edge array.
519 * \param pCreaseArray Edge crease data array.
520 * \return \c true if the pCreaseArray is filled successfully. */
521 bool GetEdgeCreaseInfoArray(FbxLayerElementArrayTemplate<double>** pCreaseArray);
522
523 /** Get crease weight by vertex index.
524 * \param pVertexIndex Vertex index.
525 * \return Crease weight value in the range [0.0 - 1.0]. */
526 double GetVertexCreaseInfo(int pVertexIndex);
527
528 /** Get vertex crease array.
529 * \param pCreaseArray Edge vertex data array.
530 * \return \c true if the pCreaseArray is filled successfully. */
531 bool GetVertexCreaseInfoArray(FbxLayerElementArrayTemplate<double>** pCreaseArray);
532
533 /** Set crease weight by edge index.
534 * \param pEdgeIndex Edge index.
535 * \param pWeight Crease weight value in the range [0.0 - 1.0].
536 * \return \c true if successfully set the crease weight. */
537 bool SetEdgeCreaseInfo(int pEdgeIndex, double pWeight);
538
539 /** Set crease weight data array.
540 * \param pWeightArray Edge crease data.
541 * \return \c true if successfully set the crease weight. */
542 bool SetEdgeCreaseInfoArray(FbxArray<double>* pWeightArray);
543
544 /** Set crease weight by vertex index.
545 * \param pVertexIndex Vertex index.
546 * \param pWeight Crease weight value in the range [0.0 - 1.0].
547 * \return \c true if successfully set the crease weight. */
548 bool SetVertexCreaseInfo(int pVertexIndex, double pWeight);
549
550 /** Set crease weight data array.
551 * \param pWeightArray Vertex crease data.
552 * \return \c true if successfully set the crease weight. */
553 bool SetVertexCreaseInfoArray(FbxArray<double>* pWeightArray);
554 //@}
555
556 /** \name Smooth mesh preview utility functions */
557 //@{
558 /** \enum ESmoothness Display Smoothness.
559 * It represents smooth mesh preview mode. This concept is not used in the FBX SDK but simply
560 * carried over so applications can access it and perform the appropriate tasks. */
561 enum ESmoothness
562 {
563 eHull, //!< Default value, not active "smooth mesh preview".
564 eRough, //!< Not active "smooth mesh preview".
565 eMedium, //!< Both display cage and smooth mesh.
566 eFine //!< Display smooth mesh.
567 };
568
569 /** \enum EBoundaryRule the boundary rule. */
570 enum EBoundaryRule
571 {
572 eLegacy, //!< Default value.
573 eCreaseAll, //!< Used for hard corner.
574 eCreaseEdge //!< Used for round corner.
575 };
576
577 /** Get display smoothness from mesh.
578 * \return Mesh smoothness.
579 * \remark It represents smooth mesh preview mode. */
580 FbxMesh::ESmoothness GetMeshSmoothness() const;
581
582 /** Set the mesh display smoothness mode.
583 * \param pSmoothness New smoothness factor.
584 * \remark It represents smooth mesh preview mode. */
585 void SetMeshSmoothness(FbxMesh::ESmoothness pSmoothness);
586
587 /** Get preview subdivision levels from mesh.
588 * \return Mesh preview subdivision levels. */
589 int GetMeshPreviewDivisionLevels() const;
590
591 /** Set mesh preview subdivision levels.
592 * \param pPreviewDivisionLevels Number of subdivisions levels. */
593 void SetMeshPreviewDivisionLevels(int pPreviewDivisionLevels);
594
595 /** Get render subdivision levels from mesh.
596 * \return Mesh render subdivision levels
597 * \remark Sometimes, render division level can be the same as preview level. */
598 int GetMeshRenderDivisionLevels() const;
599
600 /** Set mesh render subdivision levels.
601 * \param pRenderDivisionLevels Number of subdivision levels. */
602 void SetMeshRenderDivisionLevels(int pRenderDivisionLevels);
603
604 /** Query whether to display subdivisions isolines on mesh.
605 * \return The current state of the internal flag. */
606 bool GetDisplaySubdivisions() const;
607
608 /** Set the DisplySubdivisions state.
609 * \param pDisplySubdivisions New value for this flag. */
610 void SetDisplaySubdivisions(bool pDisplySubdivisions);
611
612 /** Get BoundaryRule from mesh.
613 * \return Current value of the internal state. */
614 EBoundaryRule GetBoundaryRule() const;
615
616 /** Set BoundaryRule for this mesh.
617 * \param pBoundaryRule New value for the internal state of this mesh.
618 * \remark BoundaryRule will affect the corners of smooth mesh. */
619 void SetBoundaryRule(EBoundaryRule pBoundaryRule);
620
621 /** Query whether to preserve borders when preview smooth mesh is enabled.
622 * \return The current state of the flag. */
623 bool GetPreserveBorders() const;
624
625 /** Set the state of the PreserveBorders flag.
626 * \param pPreserveBorders New value for this flag.
627 * \remark This flag value will affect smooth mesh preview results. */
628 void SetPreserveBorders(bool pPreserveBorders);
629
630 /** Query whether to preserve hard edges when preview smooth mesh.
631 * \return The current state of the flag. */
632 bool GetPreserveHardEdges() const;
633
634 /** Set the state of the PreserveHardEdges flag.
635 * \param pPreserveHardEdges New value for this flag.
636 * \remark This flag value will affect smooth mesh preview results. */
637 void SetPreserveHardEdges(bool pPreserveHardEdges);
638
639 /** Query whether to PropagateEdgeHardness when preview smooth mesh.
640 * \return The current state of the flag. */
641 bool GetPropagateEdgeHardness() const;
642
643 /** Set state of the PropagateEdgeHardness flag.
644 * \param pPropagateEdgeHardness New value for this flag.
645 * \remark This flag will affect smooth mesh preview results. */
646 void SetPropagateEdgeHardness(bool pPropagateEdgeHardness);
647 //@}
648
649 /** \name Geometry hole management utility functions */
650 //@{
651 /** Get hole flag by face index (an index to a polygon).
652 * \param pFaceIndex Index of the queried polygon.
653 * \return The hole flag for the given face. */
654 bool GetPolyHoleInfo(int pFaceIndex);
655
656 /** Get hole flags Array.
657 * \param pHoleArray Hole flags array.
658 * \return \c true if the pHoleArray is filled successfully. */
659 bool GetPolyHoleInfoArray(FbxLayerElementArrayTemplate<bool>** pHoleArray);
660
661 /** Sets the flag indicating whether the face represents a hole or not.
662 * \param pFaceIndex Index of the processed polygon.
663 * \param pIsHole If \c true, this face represent a hole.
664 * \return \c true if successfully set the hole info. */
665 bool SetPolyHoleInfo(int pFaceIndex, bool pIsHole);
666
667 /** Set hole flags array.
668 * \param pHoleArray Hole flag array.
669 * \return \c true if successfully set the hole flags. */
670 bool SetPolyHoleInfoArray(FbxArray<bool>* pHoleArray);
671 //@}
672
673 /** \name Tangents data management utility functions */
674 //@{
675 /** Generate tangents data for UVSet with specific name.
676 * Note that the UV winding order is stored in the W component of the tangent.
677 * W = 1.0 (right-handed)
678 * W = -1.0 (left-handed)
679 * In the case of a left-handed tangent, this function automatically flips the
680 * resulting binormal to correct for mirrored geometry.
681 * \param pUVSetName The UVSet name to generate tangents data with. The UVSet on the first layer is the the default UVSet to generate.
682 * \param pOverwrite If true, re-generate tangents data regardless of availability, otherwise left untouched if exist.
683 * \return \c true if successfully generated tangents data, or if already available and pOverwrite is false. */
684 bool GenerateTangentsData(const char* pUVSetName=NULL, bool pOverwrite=false);
685
686 /** Generate tangents data for UVSet in specific layer.
687 * Note that the UV winding order is stored in the W component of the tangent.
688 * W = 1.0 (right-handed)
689 * W = -1.0 (left-handed)
690 * In the case of a left-handed tangent, this function automatically flips the
691 * resulting binormal to correct for mirrored geometry.
692 * \param pUVSetLayerIndex The layer to generate tangents data with.
693 * \param pOverwrite If true, re-generate tangents data regardless of availability, otherwise left untouched if exist.
694 * \return \c true if successfully generated tangents data, or if already available and pOverwrite is false. */
695 bool GenerateTangentsData(int pUVSetLayerIndex, bool pOverwrite=false);
696
697
698 /** Generate tangents data for all UVSets in all layers.
699 * Note that the UV winding order is stored in the W component of the tangent:
700 * W = 1.0 (right-handed)
701 * W = -1.0 (left-handed)
702 * In the case of a left-handed tangent, this function automatically flips the
703 * resulting binormal to correct for mirrored geometry.
704 * \param pOverwrite If true, re-generate tangents data regardless of availability, otherwise left untouched if exist.
705 * \return \c true if successfully generated tangents data, or if already available and pOverwrite is false. */
706 bool GenerateTangentsDataForAllUVSets(bool pOverwrite=false);
707 //@}
708
709/*****************************************************************************************************************************
710** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
711*****************************************************************************************************************************/
712#ifndef DOXYGEN_SHOULD_SKIP_THIS
713 virtual FbxObject& Copy(const FbxObject& pObject);
714 virtual void Compact();
715
716 //Please use GetPolygonVertexIndex and GetPolygonVertices to access these arrays.
717 //DO NOT MODIFY them directly, otherwise unexpected behavior will occur.
718 //These members are public only for application data copy performance reasons.
719 struct PolygonDef{ int mIndex; int mSize; int mGroup; };
720
721 FbxArray<PolygonDef> mPolygons;
722 FbxArray<int> mPolygonVertices;
723 FbxArray<int> mEdgeArray;
724
725 //These are only used in context of triangulation to backup original polygon layout necessary for handling mesh cache after triangulation
726 FbxArray<PolygonDef>* mOriginalPolygons;
727 FbxArray<int>* mOriginalPolygonVertices;
728 int mOriginalControlPointsCount;
729
730 //Internal structure used to keep the mapping information between edges and polygons.
731 struct ComponentMap
732 {
733 FbxArray<int> mData; // The array to store data.
734 FbxArray<int> mOffsets; // The array to store the offsets of the data in mData.
735
736 int GetDataCount(int pIndex) { return mOffsets[pIndex + 1] - mOffsets[pIndex]; }
737 int GetData(int pIndex, int pSubIndex) { return mData[ mOffsets[pIndex] + pSubIndex ]; }
738 int GetComponentCount() { return mOffsets.GetCount() - 1; }
739 };
740 void ComputeComponentMaps(ComponentMap& pEdgeToPolyMap, ComponentMap& pPolyToEdgeMap);
741
742 // Internal structure used to keep the mapping information between the control points and the
743 // vertices referencing them
744 class ControlPointToVerticesMap
745 {
746 public:
747 ControlPointToVerticesMap();
748 ~ControlPointToVerticesMap();
749 bool Valid();
750
751 void Fill(FbxMesh* pMesh);
752
753 int GetCount();
754 bool Init(int pNbEntries);
755 void Clear();
756
757 FbxArray<int>* GetVerticesArray(int pControlPoint);
758 FbxArray<int>* operator[](int pControlPoint);
759
760 private:
761 FbxArray< FbxArray<int>* > mMap;
762 };
763 void ComputeControlPointToVerticesMap(ControlPointToVerticesMap& pMap);
764
765 // this function will compare the vertex normals with the corresponding ones in pMesh and
766 // make them similar (i.e: if pMesh(NVi) == pMesh(NVj) then make this(NVi) == this(NVj))
767 bool ConformNormalsTo(const FbxMesh* pMesh);
768
769protected:
770 virtual void Construct(const FbxObject* pFrom);
771 virtual void Destruct(bool pRecursive);
772 virtual void ContentClear();
773
774 void InitTextureIndices(FbxLayerElementTexture* pLayerElementTexture, FbxLayerElement::EMappingMode pMappingMode);
775 void RemoveTextureIndex(FbxLayerElementTexture* pLayerElementTextures, int pPolygonIndex, int pOffset);
776 void RemoveUVIndex(FbxLayerElementUV* pLayerElementUV, int pPolygonIndex, int pOffset);
777
778 bool GetBadPolyIndices(FbxArray<int>& pArrayBadPolyIndices, bool pCheckOne) const;
779
780 struct SplitEdgeData { int mOriginalEdge; bool mIsNew; };
781
782 ESmoothness mSmoothness;
783 int mPreviewDivisionLevels;
784 int mRenderDivisionLevels;
785
786 bool mDisplaySubdivisions;
787 EBoundaryRule mBoundaryRule;
788 bool mPreserveBorders;
789 bool mPreserveHardEdges;
790 bool mPropagateEdgeHardness;
791
792 struct PolygonIndexDef { int mPolygonIndex; int mSubPolygonIndex; };
793
794 struct V2PVMap
795 {
796 PolygonIndexDef* mV2PV;
797 int* mV2PVOffset;
798 int* mV2PVCount;
799 FbxArray<FbxSet<int>* > mPVEdge;
800 bool mValid;
801
802 //Used for fast search in GetMeshEdgeIndexForPolygon this array does not follow the same allocation as the above ones because
803 //it is not used in the normal BeginAddMeshEdgeIndex(). It is filled only by the call to BeginGetMeshEdgeIndexForPolygon().
804 FbxArray<int> mV2Edge;
805 } mV2PVMap;
806
807 struct EdgeLookupDef { FbxArray<int> mPVFlags; bool mValid; } mPVEndFlags;
808
809 //Finds the polygon index for the given edge
810 int FindPolygonIndex(int pEdgeIndex);
811 static int PolygonIndexCompare(const void* p1, const void* p2);
812 void PolySetTexture(FbxLayer* pLayer, int pTextureIndex, FbxLayerElement::EType pTextureType);
813 template<class T> bool GetPolygonVertexLayerElementIndex(const FbxLayerElementTemplate<T>* pLayerElement, int pPolyIndex, int pVertexIndex, int& pIndex) const;
814 template<class T> bool GetPolygonVertexLayerElementValue(const FbxLayerElementTemplate<T>* pLayerElement, int pPolyIndex, int pVertexIndex, T& pValue, bool pAllowUnmapped) const;
815
816 friend class FbxGeometryConverter;
817
818private:
819 bool GenerateTangentsData(FbxLayerElementUV* pUVSet, int pLayerIndex, bool pOverwrite=false);
820 void FillMeshEdgeTable(FbxArray<int>& pTable, int* pValue, void (*FillFct)(FbxArray<int>& pTable, int pIndex, int* pValue));
821 void ComputeNormalsPerCtrlPoint(FbxArray<VertexNormalInfo>& lNormalInfo, bool pCW=false);
822 void ComputeNormalsPerPolygonVertex(FbxArray<VertexNormalInfo>& lNormalInfo, bool pCW=false);
823 void GenerateNormalsByCtrlPoint(bool pCW);
824
825#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
826};
827
828#include <fbxsdk/fbxsdk_nsend.h>
829
830#endif /* _FBXSDK_SCENE_GEOMETRY_MESH_H_ */
831