MySources/topologyenumerator.hpp

181 lines
7.1 KiB
C++

#ifndef TOPOLOGYENUMERATOR_HPP
#define TOPOLOGYENUMERATOR_HPP
#include "patternIO.hpp"
#include "trianglepatterngeometry.hpp"
#include "trianglepattterntopology.hpp"
#include <filesystem>
#include <fstream>
#include <iostream>
//#include <nlohmann/json.hpp>
#include <string>
#include <vector>
using GraphEdge = std::pair<size_t, size_t>;
/*
* Represents a graph formed by slots on a triangle that can either be filled or
* not. The slots are three and are: 1) one slot per vertex. Each slot can hold
* a signle node. 2) one slot per edge. Each slot can hold many nodes. 3) one
* slot in the inside of the triangle. Each slot can hold multiple nodes.
* */
class TopologyEnumerator {
/*
* Holds the in a CCW order the vertex and the edge slots and then the face
* slot. [0],[1],[2] can either be 0 or 1 [3],[4],[5] are integers in [0,n]
* [6] an integer [0,n]
* */
/*
reduced nodes per slot
0
/\
/ \
2 2
/ 4 \
/ \
1----3-----1
nodes per slot
0
/\
/ \
3 5
/ 6 \
/ \
1----4-----2
slot=0 -> vi=0
slot=1 -> vi=1
slot=2 -> vi=2
...
see TrianglePatternGeometry::constructVertexVector
*/
struct TopologicalStatistics {
size_t numberOfPossibleEdges{0};
size_t numberOfCoincideEdges{0};
size_t numberOfDuplicateEdges{0};
size_t numberOfValidEdges{0};
size_t numberOfIntersectingEdgePairs{0};
size_t numberOfPatterns{0};
// size_t numberOfIntersectingEdgesOverAllPatterns{0};
size_t numberOfPatternsWithIntersectingEdges{0};
size_t numberOfPatternsWithMoreThanASingleCC{0};
size_t numberOfPatternsWithADanglingEdgeOrNode{0};
size_t numberOfPatternsWithArticulationPoints{0};
size_t numberOfValidPatterns{0};
// nlohmann::json convertToJson() const {
// nlohmann::json json;
// json["numPossibleEdges"] = numberOfPossibleEdges;
// json["numCoincideEdges"] = numberOfCoincideEdges;
// json["numDuplicateEdges"] = numberOfDuplicateEdges;
// json["numValidEdges"] = numberOfValidEdges;
// json["numIntersectingEdgePairs"] = numberOfIntersectingEdgePairs;
// json["numPatterns"] = numberOfPatterns;
// // json["numIntersectingEdgesOverAllPatterns"] =
// // numberOfIntersectingEdgesOverAllPatterns;
// json["numPatternsWithIntersectingEdges"] =
// numberOfPatternsWithIntersectingEdges;
// json["numPatternsWithNotASingleCC"] =
// numberOfPatternsWithMoreThanASingleCC;
// json["numPatternsWithDangling"] =
// numberOfPatternsWithADanglingEdgeOrNode;
// json["numPatternsWithArticulationPoints"] =
// numberOfPatternsWithArticulationPoints;
// json["numValidPatterns"] = numberOfValidPatterns;
// return json;
// }
void print(const std::string &setupString,
const std::filesystem::path &directoryPath) const {
std::cout << "The setup " << setupString << std::endl;
std::cout << "Has following statistics:" << std::endl;
std::cout << numberOfPossibleEdges
<< " possible edges with the given arrangement of nodes"
<< std::endl;
std::cout << numberOfCoincideEdges << " coincide edges" << std::endl;
std::cout << numberOfDuplicateEdges << " duplicate edges" << std::endl;
std::cout << numberOfValidEdges << " valid edges" << std::endl;
std::cout << numberOfIntersectingEdgePairs << "intersecting edge pairs "
<< std::endl;
std::cout << numberOfPatterns
<< " patterns can be generated with the given setup"
<< std::endl;
// std::cout << numberOfIntersectingEdgesOverAllPatterns
// << " intersecting edges found over all patterns" <<
// std::endl;
std::cout << numberOfPatternsWithIntersectingEdges
<< " patterns found with intersecting edges" << std::endl;
std::cout << numberOfPatternsWithMoreThanASingleCC
<< " patterns found with more than one connected components"
<< std::endl;
std::cout << numberOfPatternsWithADanglingEdgeOrNode
<< " patterns found with a dangling node or edge" << std::endl;
std::cout << numberOfPatternsWithArticulationPoints
<< " patterns found with an articulation point" << std::endl;
std::cout << numberOfValidPatterns << " valid patterns were found"
<< std::endl;
// if (!directoryPath.empty()) {
// auto json = convertToJson();
// std::ofstream file;
// file.open(std::filesystem::path(directoryPath)
// .append("statistics.csv")
// .string());
// file << "setup," << setupString << "\n";
// for (const auto &el : json.items()) {
// file << el.key() << "," << el.value() << "\n";
// }
// }
}
};
TopologicalStatistics statistics;
std::vector<size_t> numberOfNodesPerSlot;
size_t numberOfNodes;
size_t
computeCoincideEdges(const std::vector<size_t> &numberOfNodesPerSlot) const;
size_t computeNumberOfPossibleEdges(
const std::vector<size_t> &numberOfNodesPerSlot) const;
void createLabelMesh(const std::vector<vcg::Point3d> vertices,
const std::filesystem::path &savePath) const;
size_t getEdgeIndex(size_t ni0, size_t ni1) const;
public:
TopologyEnumerator();
void
computeValidPatterns(const std::vector<size_t> &reducedNumberOfNodesPerSlot);
private:
std::vector<size_t>
getCoincideEdges(const std::vector<size_t> &edgeNodeIndices) const;
bool isValidPattern(const std::string &patternIndex,
const std::vector<vcg::Point2i> &validEdges,
const size_t &numberOfDesiredEdges) const;
std::vector<vcg::Point2i>
getValidEdges(const std::vector<size_t> &numberOfNodesPerSlot,
const std::filesystem::__cxx11::path &resultsPath,
const FlatPatternGeometry &patternGeometryAllEdges,
const std::vector<vcg::Point2i> &allPossibleEdges);
std::unordered_set<size_t> computeDuplicateEdges();
std::unordered_set<size_t>
computeCoincideEdges(const std::vector<size_t> &numberOfNodesPerSlot);
void computeEdgeNodes(const std::vector<size_t> &numberOfNodesPerSlot,
std::vector<size_t> &nodesEdge0,
std::vector<size_t> &nodesEdge1,
std::vector<size_t> &nodesEdge2);
std::unordered_set<size_t>
computeDuplicateEdges(const std::vector<size_t> &numberOfNodesPerSlot);
void computeValidPatterns(
const std::vector<size_t> &numberOfNodesPerSlot,
const size_t &numberOfDesiredEdges,
const std::filesystem::path &resultsPath,
const std::vector<vcg::Point3d> &vertices,
const std::unordered_map<size_t, std::unordered_set<size_t>>
&intersectingEdges,
const std::vector<vcg::Point2i> &validEdges, PatternSet &patternsSet);
};
#endif // TOPOLOGYENUMERATOR_HPP