#ifndef FLATPATTERNGEOMETRY_HPP #define FLATPATTERNGEOMETRY_HPP #include #include #include #include "edgemesh.hpp" #include "polymesh.hpp" #include "vcgtrimesh.hpp" class PatternGeometry; using ConstPatternGeometry = PatternGeometry; class PatternGeometry : public VCGEdgeMesh { private: size_t computeTiledValence( const size_t& nodeIndex, const std::vector& numberOfNodesPerSlot) const; size_t getNodeValence(const size_t& nodeIndex) const; size_t getNodeSlot(const size_t& nodeIndex) const; void addNormals(); double baseTriangleHeight; inline static size_t fanSize{6}; std::vector vertices; const double triangleEdgeSize{1}; // radius edge std::unordered_map nodeToSlotMap; std::unordered_map correspondingNode; std::unordered_map nodeTiledValence; vcg::Triangle3 baseTriangle; void constructCorrespondingNodeMap( const std::vector& numberOfNodesPerSlot); void constructNodeToTiledValenceMap( const std::vector& numberOfNodesPerSlot); std::vector getEdgeVectorsWithVertexAsOrigin( std::vector& edgePointers, const int& vi); public: inline static VectorType DefaultNormal{0.0, 0.0, 1.0}; PatternGeometry(); /*The following function should be a copy constructor with * a const argument but this is impossible due to the * vcglib interface. * */ PatternGeometry(PatternGeometry& other); bool load(const std::filesystem::path& meshFilePath) override; void add(const std::vector& vertices); void add(const std::vector& edges); void add(const std::vector& vertices, const std::vector& edges); void add(const std::vector& numberOfNodesPerSlot, const std::vector& edges); static std::vector constructVertexVector( const std::vector& numberOfNodesPerSlot, const size_t& fanSize, const double& triangleEdgeSize); bool hasDanglingEdges(const std::vector& numberOfNodesPerSlot); bool hasValenceGreaterThan(const std::vector& numberOfNodesPerSlot, const size_t& valenceThreshold); std::vector computeVertices() const; static PatternGeometry createFan(PatternGeometry& pattern); static PatternGeometry createTile(PatternGeometry& pattern); double getTriangleEdgeSize() const; bool hasUntiledDanglingEdges(); std::unordered_map> getIntersectingEdges( size_t& numberOfIntersectingEdgePairs) const; static size_t binomialCoefficient(size_t n, size_t m) { assert(n >= m); return tgamma(n + 1) / (tgamma(m + 1) * tgamma(n - m + 1)); } bool isFullyConnectedWhenFanned(); bool hasIntersectingEdges( const std::string& patternBinaryRepresentation, const std::unordered_map>& intersectingEdges); bool isPatternValid(); size_t getFanSize() const; void add(const std::vector& vertices, const std::vector& edges); PatternGeometry(const std::vector& numberOfNodesPerSlot, const std::vector& edges); PatternGeometry(const std::filesystem::path& patternFilePath, bool addNormalsIfAbsent = true); bool createHoneycombAtom(); void copy(PatternGeometry& copyFrom); void tilePattern(VCGEdgeMesh& pattern, VCGPolyMesh& tileInto, const int& interfaceNodeIndex, const bool& shouldDeleteDanglingEdges); void scale(const double& desiredBaseTriangleCentralEdgeSize); double getBaseTriangleHeight() const; vcg::Triangle3 computeBaseTriangle() const; void updateBaseTriangle(); double computeBaseTriangleHeight() const; void updateBaseTriangleHeight(); // PatternGeometry(const std::vector &vertices, const // std::vector &edges); static std::shared_ptr // tilePattern( // std::vector &pattern, // const std::vector &connectToNeighborsVi, // const VCGPolyMesh &tileInto, // std::vector &tileIntoEdgesToTiledVi, // std::vector> &perPatternEdges); virtual void createFan(/*const std::vector &connectToNeighborsVi = std::vector(),*/ const size_t& fanSize = 6); int interfaceNodeIndex{ 3}; // TODO: Fix this. This should be automatically computed bool hasAngleSmallerThanThreshold( const std::vector& numberOfNodesPerSlot, const double& angleThreshold_degrees, const bool shouldBreak = false); vcg::Triangle3 getBaseTriangle() const; static std::shared_ptr tilePattern( PatternGeometry& pattern, const std::vector& connectToNeighborsVi, const VCGPolyMesh& tileInto, std::vector& tileIntoEdgesToTiledVi); static std::shared_ptr tilePattern( std::vector& patterns, const std::vector& connectToNeighborsVi, const VCGPolyMesh& tileInto, const std::vector& perSurfaceFacePatternIndices, std::vector& tileIntoEdgesToTiledVi, std::vector>& perPatternIndexTiledPatternEdgeIndex); std::unordered_set getInterfaceNodes( const std::vector& numberOfNodesPerSlot); bool isInterfaceConnected( const std::unordered_set& interfaceNodes); void deleteDanglingVertices() override; void deleteDanglingVertices( vcg::tri::Allocator::PointerUpdater& pu) override; }; #endif // FLATPATTERNGEOMETRY_HPP