#ifndef SIMPLEUV_UV_UNWRAPPER_H #define SIMPLEUV_UV_UNWRAPPER_H #include #include #include #include #include namespace simpleuv { class UvUnwrapper { public: void setMesh(const Mesh &mesh); void setTexelSize(float texelSize); void unwrap(); const std::vector &getFaceUvs() const; const std::vector &getChartRects() const; const std::vector &getChartSourcePartitions() const; float getTextureSize() const; private: void partition(); void splitPartitionToIslands(const std::vector &group, std::vector> &islands); void unwrapSingleIsland(const std::vector &group, int sourcePartition, bool skipCheckHoles=false); void parametrizeSingleGroup(const std::vector &verticies, const std::vector &faces, std::map &localToGlobalFacesMap, size_t faceNumToChart, int sourcePartition); bool fixHolesExceptTheLongestRing(const std::vector &verticies, std::vector &faces, size_t *remainingHoleNum=nullptr); void makeSeamAndCut(const std::vector &verticies, const std::vector &faces, std::map &localToGlobalFacesMap, std::vector &firstGroup, std::vector &secondGroup); void calculateSizeAndRemoveInvalidCharts(); void packCharts(); void finalizeUv(); void buildEdgeToFaceMap(const std::vector &group, std::map, size_t> &edgeToFaceMap); void buildEdgeToFaceMap(const std::vector &faces, std::map, size_t> &edgeToFaceMap); double distanceBetweenVertices(const Vertex &first, const Vertex &second); float areaOf3dTriangle(const Eigen::Vector3d &a, const Eigen::Vector3d &b, const Eigen::Vector3d &c); float areaOf2dTriangle(const Eigen::Vector2d &a, const Eigen::Vector2d &b, const Eigen::Vector2d &c); void triangulateRing(const std::vector &verticies, std::vector &faces, const std::vector &ring); void calculateFaceTextureBoundingBox(const std::vector &faceTextureCoords, float &left, float &top, float &right, float &bottom); Mesh m_mesh; std::vector m_faceUvs; std::map> m_partitions; std::vector, std::vector>> m_charts; std::vector> m_chartSizes; std::vector> m_scaledChartSizes; std::vector m_chartRects; std::vector m_chartSourcePartitions; bool m_segmentByNormal = true; float m_segmentDotProductThreshold = 0.0; //90 degrees float m_texelSizePerUnit = 1.0; float m_resultTextureSize = 0; bool m_segmentPreferMorePieces = true; bool m_enableRotation = true; static const std::vector m_rotateDegrees; }; } #endif