#ifndef FLATPATTERNGEOMETRY_HPP #define FLATPATTERNGEOMETRY_HPP #include "edgemesh.hpp" #include #include #include #include "vcgtrimesh.hpp" #include "polymesh.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; double computeBaseTriangleHeight() const; 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: 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 getVertices() 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::string &filename, bool addNormalsIfAbsent = true); bool createHoneycombAtom(); void copy(PatternGeometry ©From); void tilePattern(VCGEdgeMesh &pattern, VCGPolyMesh &tileInto, const int &interfaceNodeIndex, const bool &shouldDeleteDanglingEdges); void scale(const double &desiredBaseTriangleCentralEdgeSize, const int &interfaceNodeIndex); double getBaseTriangleHeight() const; vcg::Triangle3 computeBaseTriangle() const; 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); 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); 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