2020-11-27 11:47:21 +01:00
|
|
|
#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
|
2021-04-08 20:03:23 +02:00
|
|
|
computeValidPatterns(const std::vector<size_t> &reducedNumberOfNodesPerSlot, const std::string &desiredResultsPath, const int& numberOfDesiredEdges=-1);
|
2020-11-27 11:47:21 +01:00
|
|
|
|
|
|
|
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,
|
2021-02-04 13:58:41 +01:00
|
|
|
const std::filesystem::path &resultsPath,
|
2021-03-15 18:04:29 +01:00
|
|
|
const PatternGeometry &patternGeometryAllEdges,
|
2020-11-27 11:47:21 +01:00
|
|
|
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,
|
2021-03-15 18:04:29 +01:00
|
|
|
const std::vector<vcg::Point2i> &validEdges);
|
2020-11-27 11:47:21 +01:00
|
|
|
};
|
2021-04-08 20:03:23 +02:00
|
|
|
#endif // TOPOLOGYENUMERATOR_HPP
|