123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- /****************************************************************************************
-
- Copyright (C) 2015 Autodesk, Inc.
- All rights reserved.
-
- Use of this software is subject to the terms of the Autodesk license agreement
- provided at the time of installation or download, or which otherwise accompanies
- this software in either electronic or hard copy form.
-
- ****************************************************************************************/
- //! \file fbxgeometryconverter.h
- #ifndef _FBXSDK_UTILS_GEOMETRY_CONVERTER_H_
- #define _FBXSDK_UTILS_GEOMETRY_CONVERTER_H_
- #include <fbxsdk/fbxsdk_def.h>
- #include <fbxsdk/core/base/fbxarray.h>
- #include <fbxsdk/fbxsdk_nsbegin.h>
- class FbxManager;
- class FbxMesh;
- class FbxPatch;
- class FbxNurbs;
- class FbxNurbsSurface;
- class FbxNurbsCurve;
- class FbxWeightedMapping;
- class FbxSurfaceEvaluator;
- class FbxScene;
- class FbxNode;
- class FbxNodeAttribute;
- class FbxGeometry;
- /**
- * This class provides the functionality to convert geometry nodes
- * attributes (FbxMesh, FbxNurbs and FbxPatch) and mainly focuses on the two
- * major categories: Triangulation and conversion between NURBS and Patches surfaces.
- * \nosubgrouping
- */
- class FBXSDK_DLL FbxGeometryConverter
- {
- public:
- /** \name Triangulation Utilities */
- //@{
- /** Triangulate all node attributes in the scene that can be triangulated.
- * \param pScene The scene to iterate through to triangulate meshes.
- * \param pReplace If \c true, replace the original meshes with the new triangulated meshes on all the nodes, and delete the original meshes. Otherwise, original meshes are left untouched.
- * \param pLegacy If \c true, use legacy triangulation method that does not support holes in geometry. Provided for backward compatibility.
- * \return \c true if all node attributes that can be triangulated were triangulated successfully.
- * \remark The function will still iterate through all meshes regardless if one fails to triangulate, but will return false in that case. This function
- * currently only supports node attribute of type eMesh, ePatch, eNurbs or eNurbsSurface. */
- bool Triangulate(FbxScene* pScene, bool pReplace, bool pLegacy=false);
- /** Triangulate a node attribute, if supported, and preserve the skins and shapes animation channels.
- * \param pNodeAttribute Pointer to the node containing the geometry to triangulate.
- * \param pReplace If \c true, replace the original geometry with the new triangulated geometry on the nodes, and delete the original geometry.
- * Otherwise, the original geometry is left untouched, the new one is added to the nodes, and becomes the default one.
- * \param pLegacy If \c true, use legacy triangulation method that does not support holes in geometry. Provided for backward compatibility.
- * \return The newly created node attribute if successful, otherwise NULL. If node attribute type is not supported by triangulation, it returns the original node attribute.
- * \remark This function currently only supports node attribute of type eMesh, ePatch, eNurbs or eNurbsSurface. If the node attribute does not support triangulation,
- * or if it is already triangulated, this function will return pNodeAttribute. */
- FbxNodeAttribute* Triangulate(FbxNodeAttribute* pNodeAttribute, bool pReplace, bool pLegacy=false);
- /** Compute a "vertex-correspondence" table that helps passing from source to destination geometry.
- * \param pSrcGeom Pointer to the source geometry.
- * \param pDstGeom Pointer to the destination geometry.
- * \param pSrcToDstWeightedMapping Pointer to the weighted mapping table.
- * \param pSwapUV Set to \c true to swap UVs.
- * \return \c true on success, \c false if the function fails to compute the correspondence.
- * \remark Skins and shapes are also converted to fit the alternate geometry. */
- bool ComputeGeometryControlPointsWeightedMapping(FbxGeometry* pSrcGeom, FbxGeometry* pDstGeom, FbxWeightedMapping* pSrcToDstWeightedMapping, bool pSwapUV=false);
- //@}
- /**
- * \name Geometry Conversion
- */
- //@{
- /** Convert from patch to nurb.
- * \param pPatch Pointer to the patch to convert.
- * \return Created nurb or \c NULL if the conversion fails.
- * \remarks The patch must be of type eBSpline, eBezier or eLinear.
- */
- FbxNurbs* ConvertPatchToNurbs(FbxPatch *pPatch);
- /** Convert a patch contained in a node to a nurb. Use this function to preserve the patch's
- * skins and shapes animation channels.
- * \param pNode Pointer to the node containing the patch.
- * \return \c true on success, \c false if the node attribute is not a patch.
- * \remarks The patch must be of type eBSpline, eBezier or eLinear.
- */
- bool ConvertPatchToNurbsInPlace(FbxNode* pNode);
- /** Convert a patch to nurb surface.
- * \param pPatch Pointer to the patch to convert.
- * \return Created nurb surface or \c NULL if conversion fails.
- * \remarks The patch must be of type eBSpline, eBezier or eLinear.
- */
- FbxNurbsSurface* ConvertPatchToNurbsSurface(FbxPatch *pPatch);
- /** Convert a patch contained in a node to a nurb surface. Use this function to preserve
- * the patch's skins and shapes animation channels.
- * \param pNode Pointer to the node containing the patch.
- * \return \c true on success, \c false if the node attribute is not a patch.
- * \remarks The patch must be of type eBSpline, eBezier or eLinear.
- */
- bool ConvertPatchToNurbsSurfaceInPlace(FbxNode* pNode);
- /** Convert a FbxNurbs to a FbxNurbsSurface
- * \param pNurbs Pointer to the original nurb
- * \return A FbxNurbsSurface that is equivalent to the original nurb.
- */
- FbxNurbsSurface* ConvertNurbsToNurbsSurface( FbxNurbs* pNurbs );
- /** Convert a FbxNurbsSurface to a FbxNurbs
- * \param pNurbs Pointer to the original nurbs surface
- * \return A FbxNurbs that is equivalent to the original nurbs surface.
- */
- FbxNurbs* ConvertNurbsSurfaceToNurbs( FbxNurbsSurface* pNurbs );
- /** Convert a nurb, contained in a node, to a nurbs surface. Use this function to preserve
- * the nurb's skins and shapes animation channels.
- * \param pNode Pointer to the node containing the nurb.
- * \return \c true on success, \c false otherwise
- */
- bool ConvertNurbsToNurbsSurfaceInPlace(FbxNode* pNode);
- /** Convert a nurb contained in a node to a nurbs surface. Use this function to preserve
- * the nurb's skins and shapes animation channels.
- * \param pNode Pointer to the node containing the nurbs surface.
- * \return \c true on success, \c false otherwise
- */
- bool ConvertNurbsSurfaceToNurbsInPlace(FbxNode* pNode);
- //@}
- /**
- * \name Nurb UV and Links Swapping
- */
- //@{
- /** Flip UV and/or skin clusters of a nurb.
- * \param pNurbs Pointer to the Source nurb.
- * \param pSwapUV Set to \c true to swap the UVs.
- * \param pSwapClusters Set to \c true to swap the control point indices of clusters.
- * \return A flipped FbxNurbs, or \c NULL if the function fails.
- */
- FbxNurbs* FlipNurbs(FbxNurbs* pNurbs, bool pSwapUV, bool pSwapClusters);
- /** Flip UV and/or skin clusters of a nurb surface.
- * \param pNurbs Pointer to the Source nurb surface.
- * \param pSwapUV Set to \c true to swap the UVs.
- * \param pSwapClusters Set to \c true to swap the control point indices of clusters.
- * \return A flipped FbxNurbsSurface, or \c NULL if the function fails.
- */
- FbxNurbsSurface* FlipNurbsSurface(FbxNurbsSurface* pNurbs, bool pSwapUV, bool pSwapClusters);
- //@}
- /**
- * \name Normals By Polygon Vertex Emulation
- */
- //@{
- /** Emulate normals by polygon vertex mode for a mesh.
- * \param pMesh Pointer to the mesh object.
- * \return \c true on success, \c false if the number of normals in the
- * mesh and in its associated shapes don't match the number of polygon
- * vertices.
- * \remarks For applications that only supports normals by control points,
- * this function duplicates control points to equal the
- * number of polygon vertices. skins and shapes are also converted.
- * As preconditions:
- * -# polygons must have been created
- * -# the number of normals in the mesh and in its associated shapes must match the
- * number of polygon vertices.
- */
- bool EmulateNormalsByPolygonVertex(FbxMesh* pMesh);
- /** Create edge smoothing information from polygon-vertex mapped normals.
- * Existing smoothing information is removed and edge data is created if
- * none exists on the mesh.
- * \param pMesh The mesh used to generate edge smoothing.
- * \return \c true on success, \c false otherwise.
- * \remarks The edge smoothing data is placed on Layer 0 of the mesh.
- * Normals do not need to be on Layer 0, since the first layer with
- * per polygon vertex normals is used.
- */
- bool ComputeEdgeSmoothingFromNormals( FbxMesh* pMesh ) const;
- /** Convert edge smoothing to polygon smoothing group.
- * Existing smoothing information is replaced.
- *
- * \param pMesh The mesh that contains the smoothing to be converted.
- * \param pIndex The index of the layer smoothing to be converted.
- * \return \c true on success, \c false otherwise.
- * \remarks The smoothing group is bitwise. Each bit of the integer represents
- * one smoothing group. Therefore, there is a maximum of 32 smoothing groups.
- */
- bool ComputePolygonSmoothingFromEdgeSmoothing( FbxMesh* pMesh, int pIndex=0 ) const;
- /** Convert polygon smoothing group to edge smoothing.
- * Existing smoothing information is replaced.
- *
- * \param pMesh The mesh that contains the smoothing to be converted.
- * \param pIndex The index of the layer smoothing to be converted
- * \return \c true on success, \c false otherwise.
- */
- bool ComputeEdgeSmoothingFromPolygonSmoothing( FbxMesh* pMesh, int pIndex=0 ) const;
- //@}
- /** \name Split Mesh Per Materials */
- //@{
- /** Split all the mesh in the scene per material.
- * \param pScene The scene to iterate through to split meshes.
- * \param pReplace If \c true, replace the original mesh with new ones and delete the original meshes, but *only* if they got split into multiple meshes, otherwise they are left untouched.
- * \return \c true if all splitable mesh were successfully split, \c false otherwise.
- * \remark The function will still iterate through all meshes regardless if one fails to split, but will return false in that case. */
- bool SplitMeshesPerMaterial(FbxScene* pScene, bool pReplace);
- /** Split mesh per material.
- * \param pMesh The mesh that will be split if it has multiple materials assigned.
- * \param pReplace If \c true, replace the original mesh with new one and delete the original mesh, but *only* if they got split into multiple meshes, otherwise left untouched.
- * \return \c true on success, \c false otherwise.
- * \remark The function will fail if the mapped material is not per face (FbxLayerElement::eByPolygon) or if a material is multi-layered. It will create as many meshes as
- * there are materials applied to it. If one mesh have some polygons with material A, some polygons with material B, and some polygons with NO material, 3 meshes distinct
- * will be created. The newly created meshes will be automatically attached to the same FbxNode that holds the original FbxMesh. If the original mesh have tangents, they will
- * be regenerated on the new meshes. */
- bool SplitMeshPerMaterial(FbxMesh* pMesh, bool pReplace);
- //@}
- /** Re-parent nodes at root node level under a new node to re-center them at world center.
- * Basically, this function calculates the scene bounding box in world coordinates, and test if the center of that bounding box distance from the
- * world center is larger or equal than the threshold. If true, a new node with the proper negative offset position will become the new parent of all nodes at root node level.
- * \param pScene The scene to process.
- * \param pThreshold Threshold at which all nodes will be re-centered.
- * \return \c true if any nodes were re-centered, otherwise \c false. */
- bool RecenterSceneToWorldCenter(FbxScene* pScene, FbxDouble pThreshold);
- /**
- * Merge multiple meshes to one mesh.
- * The method will merge:
- * a) mesh vertex;
- * b) mesh polygon;
- * c) mesh edge;
- * d) all mesh elements; only the layer 0 elements is merged.
- * e) if there are skins for old mesh, merge these skins. The new skin clusters link to old skeletons.
- *
- * \param pMeshNodes FBX nodes that hold multiple meshes. These meshes will be merged.
- * \param pNodeName Name of new mesh node.
- * \param pScene The scene that will contain the new mesh node.
- * \return The new mesh node if merge successfully, otherwise NULL is returned.
- * \remarks This method creates a new mesh, leaving the source mesh unchanged.
- * The transform of new mesh node is: translate (0, 0, 0), rotation (0, 0, 0), scale (1, 1, 1).
- * For layer element material, normal, smoothing, UV set, vertex color, binormal, tangent and polygon group,
- * if any mesh misses these element, the merge for this kind of element is skipped.
- * For layer element crease, hole, visibility and user data, if any mesh has such element, the kind of element
- * will be merged. The missing element will be filled with default values.
- * For meshes with skin binding, if the pose of frame 0 is different with bind pose, the new mesh will be distorted.
- */
- FbxNode* MergeMeshes(FbxArray<FbxNode*>& pMeshNodes, const char* pNodeName, FbxScene* pScene);
- /**
- * Cleanup or remove degenerated meshes.
- * \param pScene The scene to process.
- * \param pAffectedNodes The list of nodes that have been affected by this operation.
- * \remarks If the cleaned-up mesh becomes invalid, it is removed entirely.
- */
- void RemoveBadPolygonsFromMeshes(FbxScene* pScene, FbxArray<FbxNode*>* pAffectedNodes = NULL);
- /*****************************************************************************************************************************
- ** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
- *****************************************************************************************************************************/
- #ifndef DOXYGEN_SHOULD_SKIP_THIS
- FbxGeometryConverter(FbxManager* pManager);
- ~FbxGeometryConverter();
- private:
- FbxMesh* TriangulateMeshInternal(const FbxMesh* pMesh);
- FbxMesh* TriangulateMeshInternalLegacy(const FbxMesh* pMesh);
- FbxMesh* TriangulatePatchInternal(const FbxPatch* pPatch);
- FbxMesh* TriangulateNurbsInternal(const FbxNurbs* pNurbs);
- bool AddAlternateGeometry(FbxNode* pNode, FbxGeometry* pSrcGeom, FbxGeometry* pAltGeom, FbxWeightedMapping* pSrcToAltWeightedMapping, bool pConvertDeformations);
- bool ConvertGeometryAnimation(FbxNode* pNode, FbxGeometry* pSrcGeom, FbxGeometry* pDstGeom);
- void ReplaceNodeAttribute(FbxNode* pNode, FbxNodeAttribute* pNewNodeAttr);
- bool AddTriangulatedMeshGeometry(FbxNode* pNode, int pUVStepCoeff);
- bool CreateAndCopyLayerElement(FbxMesh *pNewMesh, FbxMesh *pRefMesh);
- bool SetLayerElements(FbxMesh *pNewMesh, FbxMesh *pMesh, int pPolygonIndex, int pPolyPointIndex, int pLoopIndex, bool pIsSearched, bool pIsEndPolygon);
- /** FbxTriangulation
- * \param Index Output array of triangle indices
- * \param pNumSide Input number of sides of the polygon to triangulate
- * -- Triangulation algorithm is strip, Sorting vertex index for strip in clockwise.
- *
- * 2 3 4
- * 0----------0---------0
- * / `
- * / ` 5
- * 1 / 0
- * 0 /
- * ` /
- * ` /
- * 0 0-----0-------------0 6
- * 7
- * The result of this one will be [{0,1,2},{2,3,0},{0,3,7},{3,4,7},{7,4,6},{4,5,6}]
- */
- static void FbxTriangulation(int *Index, int pNumSide);
- bool ComputePatchToMeshControlPointsWeightedMapping(FbxPatch* pSrcPatch, FbxMesh* pDstMesh, FbxWeightedMapping* pMapping, bool pSwapUV=false);
- bool ComputeNurbsToMeshControlPointsWeightedMapping(FbxNurbsSurface* pSrcNurbs, FbxMesh* pDstMesh, FbxWeightedMapping* pMapping, bool pRescaleUVs=false, bool pSwapUV=false);
- void InitializeWeightInControlPoints(FbxGeometryBase* pGeometry);
- void InitializeWeightInNormals(FbxLayerContainer* pLayerContainer);
- void TriangulateContinuousSurface(FbxMesh* pMesh, FbxSurfaceEvaluator* pSurface, FbxUInt pPointCountX, FbxUInt pPointCountY, bool ClockWise=false);
- void CheckForZeroWeightInShape(FbxGeometry *pGeometry);
- FbxMesh* CreateMeshFromParametricSurface(const FbxGeometry* pGeometry);
- FbxNurbs* CreateNurbsFromPatch(FbxPatch* pPatch);
- FbxNurbsSurface* CreateNurbsSurfaceFromPatch(FbxPatch* pPatch);
- void ConvertShapes(const FbxGeometry* pSource, FbxGeometry* pDestination, FbxSurfaceEvaluator* pEvaluator, int pUCount, int pVCount);
- void ConvertShapes(const FbxGeometry* pSource, FbxGeometry* pDestination, FbxWeightedMapping* pSourceToDestinationMapping);
- void ConvertClusters(const FbxGeometry* pSource, FbxGeometry* pDestination, FbxWeightedMapping* pSourceToDestinationMapping);
- void ConvertClusters(FbxArray<FbxCluster*> const& pSourceClusters, int pSourceControlPointsCount, FbxArray<FbxCluster*>& pDestinationClusters, int pDestinationControlPointsCount, FbxWeightedMapping* pSourceToDestinationMapping);
- void BuildClusterToSourceMapping(FbxArray<FbxCluster*> const& pSourceClusters, FbxWeightedMapping* pClusterToSourceMapping);
- void CheckClusterToSourceMapping(FbxWeightedMapping* pClusterToSourceMapping);
- void ConvertCluster(int pSourceClusterIndex, FbxWeightedMapping* pClusterToSourceMapping, FbxWeightedMapping* pSourceToDestinationMapping, FbxCluster* pDestinationCluster);
- void DuplicateControlPoints(FbxArray<FbxVector4>& pControlPoints, FbxArray<int>& pPolygonVertices);
- void UpdatePolygon(FbxMesh *pNewMesh, FbxMesh const *pRefMesh, int pPolygonIndex, int* pNewIndex, int &pVerticeIndexMeshTriangulated, int &pPolygonIndexMeshTriangulated);
- void UpdatePolygon(FbxMesh *pNewMesh, FbxMesh const *pRefMesh, int pPolygonIndex, int* pNewIndex, int &pVerticeIndexMeshTriangulated, int &pPolygonIndexMeshTriangulated, int pTriangleNum);
- void ResizePolygon(FbxMesh *pNewMesh, int pNewCountVertices = 0, int pNewCountPolygons =0, bool pClearFlag = true);
- template <class T1, class T2> void ConvertNurbs(T1* pNewNurbs, T2* pOldNurb);
- bool CopyAnimationCurves(FbxNode* pNode, FbxGeometry* pNewGeometry);
- bool FlipNurbsCurve(FbxNurbsCurve* pCurve) const;
- void FlipControlPoints(FbxGeometryBase* pPoints, int pUCount, int pVCount) const;
- bool ConvertMaterialReferenceMode(FbxMesh* pMeshRef) const;
- void RevertMaterialReferenceModeConversion(FbxMesh* pMeshRef) const;
- FbxManager* mManager;
- friend class FbxWriter3ds;
- #endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
- };
- #include <fbxsdk/fbxsdk_nsend.h>
- #endif /* _FBXSDK_UTILS_GEOMETRY_CONVERTER_H_ */
|