Refactoring
This commit is contained in:
parent
e9707e2cfb
commit
a7fdf431dd
32
edgemesh.cpp
32
edgemesh.cpp
|
@ -1,5 +1,6 @@
|
||||||
#include "edgemesh.hpp"
|
#include "edgemesh.hpp"
|
||||||
#include "vcg/simplex/face/topology.h"
|
#include "vcg/simplex/face/topology.h"
|
||||||
|
#include <wrap/io_trimesh/import.h>
|
||||||
//#include <wrap/nanoply/include/nanoplyWrapper.hpp>
|
//#include <wrap/nanoply/include/nanoplyWrapper.hpp>
|
||||||
#include <wrap/io_trimesh/export.h>
|
#include <wrap/io_trimesh/export.h>
|
||||||
#include <wrap/io_trimesh/import.h>
|
#include <wrap/io_trimesh/import.h>
|
||||||
|
@ -26,7 +27,7 @@ Eigen::MatrixX3d VCGEdgeMesh::getEigenEdgeNormals() const {
|
||||||
return eigenEdgeNormals;
|
return eigenEdgeNormals;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VCGEdgeMesh::save(const std::filesystem::__cxx11::path &meshFilePath)
|
bool VCGEdgeMesh::save(const std::filesystem::path &meshFilePath)
|
||||||
{
|
{
|
||||||
std::string filename = meshFilePath;
|
std::string filename = meshFilePath;
|
||||||
if (filename.empty()) {
|
if (filename.empty()) {
|
||||||
|
@ -41,6 +42,9 @@ bool VCGEdgeMesh::save(const std::filesystem::__cxx11::path &meshFilePath)
|
||||||
mask |= vcg::tri::io::Mask::IOM_VERTNORMAL;
|
mask |= vcg::tri::io::Mask::IOM_VERTNORMAL;
|
||||||
mask |= vcg::tri::io::Mask::IOM_VERTCOLOR;
|
mask |= vcg::tri::io::Mask::IOM_VERTCOLOR;
|
||||||
// if (nanoply::NanoPlyWrapper<VCGEdgeMesh>::SaveModel(filename.c_str(), *this, mask, false) != 0) {
|
// if (nanoply::NanoPlyWrapper<VCGEdgeMesh>::SaveModel(filename.c_str(), *this, mask, false) != 0) {
|
||||||
|
if (std::filesystem::is_directory(meshFilePath.parent_path())) {
|
||||||
|
std::filesystem::create_directories(meshFilePath.parent_path());
|
||||||
|
}
|
||||||
if (vcg::tri::io::Exporter<VCGEdgeMesh>::Save(*this, filename.c_str(), mask) != 0) {
|
if (vcg::tri::io::Exporter<VCGEdgeMesh>::Save(*this, filename.c_str(), mask) != 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -247,7 +251,7 @@ bool VCGEdgeMesh::load(const std::filesystem::__cxx11::path &meshFilePath)
|
||||||
// return true;
|
// return true;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
bool VCGEdgeMesh::loadUsingDefaultLoader(const std::string &plyFilename)
|
bool VCGEdgeMesh::loadUsingDefaultLoader(const std::string &plyFilePath)
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
// assert(plyFileHasAllRequiredFields(plyFilename));
|
// assert(plyFileHasAllRequiredFields(plyFilename));
|
||||||
|
@ -259,7 +263,11 @@ bool VCGEdgeMesh::loadUsingDefaultLoader(const std::string &plyFilename)
|
||||||
mask |= vcg::tri::io::Mask::IOM_EDGEINDEX;
|
mask |= vcg::tri::io::Mask::IOM_EDGEINDEX;
|
||||||
// if (nanoply::NanoPlyWrapper<VCGEdgeMesh>::LoadModel(plyFilename.c_str(),
|
// if (nanoply::NanoPlyWrapper<VCGEdgeMesh>::LoadModel(plyFilename.c_str(),
|
||||||
// *this, mask) != 0) {
|
// *this, mask) != 0) {
|
||||||
if (vcg::tri::io::Importer<VCGEdgeMesh>::Open(*this, plyFilename.c_str(), mask) != 0) {
|
const int loadErrorCode = vcg::tri::io::Importer<VCGEdgeMesh>::Open(*this,
|
||||||
|
plyFilePath.c_str(),
|
||||||
|
mask);
|
||||||
|
if (loadErrorCode != 0) {
|
||||||
|
std::cerr << vcg::tri::io::Importer<VCGEdgeMesh>::ErrorMsg(loadErrorCode) << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -358,7 +366,7 @@ void VCGEdgeMesh::set(const std::vector<double> &vertexPositions, const std::vec
|
||||||
eIt->cV(0)->N() = n;
|
eIt->cV(0)->N() = n;
|
||||||
eIt->cV(1)->N() = n;
|
eIt->cV(1)->N() = n;
|
||||||
}
|
}
|
||||||
removeDuplicateVertices();
|
// removeDuplicateVertices();
|
||||||
|
|
||||||
updateEigenEdgeAndVertices();
|
updateEigenEdgeAndVertices();
|
||||||
}
|
}
|
||||||
|
@ -438,6 +446,22 @@ void VCGEdgeMesh::printVertexCoordinates(const size_t &vi) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef POLYSCOPE_DEFINED
|
#ifdef POLYSCOPE_DEFINED
|
||||||
|
void VCGEdgeMesh::markVertices(const std::vector<size_t> &vertsToMark)
|
||||||
|
{
|
||||||
|
if (vertsToMark.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::array<double, 3>> nodeColors(VN(), {0, 0, 0});
|
||||||
|
for (const size_t vi : vertsToMark) {
|
||||||
|
nodeColors[vi] = {1, 0, 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
polyscope::getCurveNetwork(getLabel())
|
||||||
|
->addNodeColorQuantity("Marked vertices" + getLabel(), nodeColors)
|
||||||
|
->setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: make const getEigenVertices is not
|
//TODO: make const getEigenVertices is not
|
||||||
polyscope::CurveNetwork *VCGEdgeMesh::registerForDrawing(
|
polyscope::CurveNetwork *VCGEdgeMesh::registerForDrawing(
|
||||||
const std::optional<std::array<double, 3>> &desiredColor,
|
const std::optional<std::array<double, 3>> &desiredColor,
|
||||||
|
|
|
@ -3,11 +3,10 @@
|
||||||
#include "beam.hpp"
|
#include "beam.hpp"
|
||||||
#include "mesh.hpp"
|
#include "mesh.hpp"
|
||||||
#include "utilities.hpp"
|
#include "utilities.hpp"
|
||||||
|
#include <array>
|
||||||
|
#include <optional>
|
||||||
#include <vcg/complex/complex.h>
|
#include <vcg/complex/complex.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <wrap/io_trimesh/import.h>
|
|
||||||
#include <optional>
|
|
||||||
#include <array>
|
|
||||||
|
|
||||||
#ifdef POLYSCOPE_DEFINED
|
#ifdef POLYSCOPE_DEFINED
|
||||||
#include <polyscope/curve_network.h>
|
#include <polyscope/curve_network.h>
|
||||||
|
@ -111,11 +110,13 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void markVertices(const std::vector<size_t> &vertsToMark);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void GeneratedRegularSquaredPattern(const double angleDeg,
|
void GeneratedRegularSquaredPattern(const double angleDeg,
|
||||||
std::vector<std::vector<vcg::Point2d>> &pattern,
|
std::vector<std::vector<vcg::Point2d>> &pattern,
|
||||||
const size_t &desiredNumberOfSamples);
|
const size_t &desiredNumberOfSamples);
|
||||||
bool loadUsingDefaultLoader(const std::string &plyFilename);
|
bool loadUsingDefaultLoader(const std::string &plyFilePath);
|
||||||
};
|
};
|
||||||
|
|
||||||
using VectorType = VCGEdgeMesh::CoordType;
|
using VectorType = VCGEdgeMesh::CoordType;
|
||||||
|
|
|
@ -109,17 +109,19 @@ inline int getParameterIndex(const std::string &s)
|
||||||
struct Settings
|
struct Settings
|
||||||
{
|
{
|
||||||
inline static std::string defaultFilename{"OptimizationSettings.json"};
|
inline static std::string defaultFilename{"OptimizationSettings.json"};
|
||||||
std::array<double, NumberOfBaseSimulationScenarios> baseScenarioMaxMagnitudes{0,
|
// std::array<double, NumberOfBaseSimulationScenarios> baseScenarioMaxMagnitudes{0.590241,
|
||||||
3,
|
// 0.888372,
|
||||||
0.95,
|
// 0.368304,
|
||||||
0.087,
|
// 0.0127508,
|
||||||
1.9,
|
// 1.18079,
|
||||||
/*3*/ 0}; //custom
|
// 0}; //final
|
||||||
// std::array<double, NumberOfBaseSimulationScenarios> baseScenarioMaxMagnitudes{2.74429,
|
std::array<double, NumberOfBaseSimulationScenarios> baseScenarioMaxMagnitudes{0.590241 / 3,
|
||||||
// 5.9173,
|
0.588372 / 3,
|
||||||
// 0.493706,
|
0.368304,
|
||||||
// 0.0820769,
|
0.1,
|
||||||
// 1.57789};
|
1.18 / 2,
|
||||||
|
0}; //final
|
||||||
|
// std::array<double, NumberOfBaseSimulationScenarios> baseScenarioMaxMagnitudes{0, 0, 0, 0.1, 0};
|
||||||
|
|
||||||
// std::array<double, NumberOfBaseSimulationScenarios>
|
// std::array<double, NumberOfBaseSimulationScenarios>
|
||||||
// baseScenarioMaxMagnitudes{20.85302947095844,
|
// baseScenarioMaxMagnitudes{20.85302947095844,
|
||||||
|
@ -235,6 +237,8 @@ struct Settings
|
||||||
bool operator==(const ObjectiveWeights &other) const;
|
bool operator==(const ObjectiveWeights &other) const;
|
||||||
};
|
};
|
||||||
std::array<ObjectiveWeights, NumberOfBaseSimulationScenarios> perBaseScenarioObjectiveWeights;
|
std::array<ObjectiveWeights, NumberOfBaseSimulationScenarios> perBaseScenarioObjectiveWeights;
|
||||||
|
// std::array<ObjectiveWeights, NumberOfBaseSimulationScenarios> perBaseScenarioObjectiveWeights{
|
||||||
|
// {{1.95, 0.05}, {0.87, 1.13}, {0.37, 1.63}, {0.01, 1.99}, {0.94, 1.06}, {1.2, 0.8}}};
|
||||||
std::array<std::pair<double, double>, NumberOfBaseSimulationScenarios>
|
std::array<std::pair<double, double>, NumberOfBaseSimulationScenarios>
|
||||||
convertObjectiveWeightsToPairs() const
|
convertObjectiveWeightsToPairs() const
|
||||||
{
|
{
|
||||||
|
@ -549,7 +553,7 @@ struct Settings
|
||||||
|
|
||||||
PatternGeometry baseTriangleFullPattern; //non-fanned,non-tiled full pattern
|
PatternGeometry baseTriangleFullPattern; //non-fanned,non-tiled full pattern
|
||||||
vcg::Triangle3<double> baseTriangle;
|
vcg::Triangle3<double> baseTriangle;
|
||||||
std::string notes;
|
// std::string notes;
|
||||||
|
|
||||||
//Data gathered for csv exporting
|
//Data gathered for csv exporting
|
||||||
struct ObjectiveValues
|
struct ObjectiveValues
|
||||||
|
@ -562,7 +566,9 @@ struct Settings
|
||||||
std::vector<double> perSimulationScenario_rotational;
|
std::vector<double> perSimulationScenario_rotational;
|
||||||
std::vector<double> perSimulationScenario_total;
|
std::vector<double> perSimulationScenario_total;
|
||||||
std::vector<double> perSimulationScenario_total_unweighted;
|
std::vector<double> perSimulationScenario_total_unweighted;
|
||||||
|
|
||||||
} objectiveValue;
|
} objectiveValue;
|
||||||
|
|
||||||
std::vector<double> perScenario_fullPatternPotentialEnergy;
|
std::vector<double> perScenario_fullPatternPotentialEnergy;
|
||||||
std::vector<double> objectiveValueHistory;
|
std::vector<double> objectiveValueHistory;
|
||||||
std::vector<size_t> objectiveValueHistory_iteration;
|
std::vector<size_t> objectiveValueHistory_iteration;
|
||||||
|
@ -573,7 +579,7 @@ struct Settings
|
||||||
{
|
{
|
||||||
bool exportPE{false};
|
bool exportPE{false};
|
||||||
bool exportIterationOfMinima{false};
|
bool exportIterationOfMinima{false};
|
||||||
bool exportRawObjectiveValue{true};
|
bool exportRawObjectiveValue{false};
|
||||||
CSVExportingSettings() {}
|
CSVExportingSettings() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -589,6 +595,53 @@ struct Settings
|
||||||
inline static std::string fullPatternYoungsModulus{"youngsModulus"};
|
inline static std::string fullPatternYoungsModulus{"youngsModulus"};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void saveObjectiveValuePlot(const std::filesystem::path &outputImageDirPath) const
|
||||||
|
{
|
||||||
|
std::vector<std::string> scenarioLabels(objectiveValue.perSimulationScenario_total.size());
|
||||||
|
const double colorAxial = 1;
|
||||||
|
const double colorShear = 3;
|
||||||
|
const double colorBending = 5;
|
||||||
|
const double colorDome = 0.1;
|
||||||
|
const double colorSaddle = 0;
|
||||||
|
std::vector<double> colors(objectiveValue.perSimulationScenario_total.size());
|
||||||
|
for (int scenarioIndex = 0; scenarioIndex < scenarioLabels.size(); scenarioIndex++) {
|
||||||
|
scenarioLabels[scenarioIndex] = reducedPatternSimulationJobs[scenarioIndex]->getLabel();
|
||||||
|
if (scenarioLabels[scenarioIndex].rfind("Axial", 0) == 0) {
|
||||||
|
colors[scenarioIndex] = colorAxial;
|
||||||
|
|
||||||
|
} else if (scenarioLabels[scenarioIndex].rfind("Shear", 0) == 0) {
|
||||||
|
colors[scenarioIndex] = colorShear;
|
||||||
|
|
||||||
|
} else if (scenarioLabels[scenarioIndex].rfind("Bending", 0) == 0) {
|
||||||
|
colors[scenarioIndex] = colorBending;
|
||||||
|
|
||||||
|
} else if (scenarioLabels[scenarioIndex].rfind("Dome", 0) == 0) {
|
||||||
|
colors[scenarioIndex] = colorDome;
|
||||||
|
} else if (scenarioLabels[scenarioIndex].rfind("Saddle", 0) == 0) {
|
||||||
|
colors[scenarioIndex] = colorSaddle;
|
||||||
|
} else {
|
||||||
|
std::cerr << "Label could not be identified" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::vector<double> y(objectiveValue.perSimulationScenario_total.size());
|
||||||
|
for (int scenarioIndex = 0; scenarioIndex < scenarioLabels.size(); scenarioIndex++) {
|
||||||
|
y[scenarioIndex]
|
||||||
|
// = optimizationResults.objectiveValue.perSimulationScenario_rawTranslational[scenarioIndex]
|
||||||
|
// + optimizationResults.objectiveValue.perSimulationScenario_rawRotational[scenarioIndex];
|
||||||
|
= objectiveValue.perSimulationScenario_total_unweighted[scenarioIndex];
|
||||||
|
}
|
||||||
|
std::vector<double> x = matplot::linspace(0, y.size() - 1, y.size());
|
||||||
|
std::vector<double> markerSizes(y.size(), 5);
|
||||||
|
Utilities::createPlot("scenario index",
|
||||||
|
"error",
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
markerSizes,
|
||||||
|
colors,
|
||||||
|
std::filesystem::path(outputImageDirPath)
|
||||||
|
.append("perScenarioObjectiveValues.svg"));
|
||||||
|
}
|
||||||
|
|
||||||
void save(const std::string &saveToPath, const bool shouldExportDebugFiles = false)
|
void save(const std::string &saveToPath, const bool shouldExportDebugFiles = false)
|
||||||
{
|
{
|
||||||
//clear directory
|
//clear directory
|
||||||
|
@ -632,14 +685,14 @@ struct Settings
|
||||||
json_optimizationResults[JsonKeys::FullPatternLabel] = baseTriangleFullPattern.getLabel();
|
json_optimizationResults[JsonKeys::FullPatternLabel] = baseTriangleFullPattern.getLabel();
|
||||||
|
|
||||||
//potential energies
|
//potential energies
|
||||||
const int numberOfSimulationJobs = fullPatternSimulationJobs.size();
|
// const int numberOfSimulationJobs = fullPatternSimulationJobs.size();
|
||||||
std::vector<double> fullPatternPE(numberOfSimulationJobs);
|
// std::vector<double> fullPatternPE(numberOfSimulationJobs);
|
||||||
for (int simulationScenarioIndex = 0; simulationScenarioIndex < numberOfSimulationJobs;
|
// for (int simulationScenarioIndex = 0; simulationScenarioIndex < numberOfSimulationJobs;
|
||||||
simulationScenarioIndex++) {
|
// simulationScenarioIndex++) {
|
||||||
fullPatternPE[simulationScenarioIndex]
|
// fullPatternPE[simulationScenarioIndex]
|
||||||
= perScenario_fullPatternPotentialEnergy[simulationScenarioIndex];
|
// = perScenario_fullPatternPotentialEnergy[simulationScenarioIndex];
|
||||||
}
|
// }
|
||||||
json_optimizationResults[JsonKeys::FullPatternPotentialEnergies] = fullPatternPE;
|
// json_optimizationResults[JsonKeys::FullPatternPotentialEnergies] = fullPatternPE;
|
||||||
json_optimizationResults[JsonKeys::fullPatternYoungsModulus] = fullPatternYoungsModulus;
|
json_optimizationResults[JsonKeys::fullPatternYoungsModulus] = fullPatternYoungsModulus;
|
||||||
////Save to json file
|
////Save to json file
|
||||||
std::filesystem::path jsonFilePath(
|
std::filesystem::path jsonFilePath(
|
||||||
|
@ -678,13 +731,28 @@ struct Settings
|
||||||
}
|
}
|
||||||
pReducedPatternSimulationJob->save(reducedPatternDirectoryPath.string());
|
pReducedPatternSimulationJob->save(reducedPatternDirectoryPath.string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// constexpr bool shouldSaveObjectiveValuePlot = shouldExportDebugFiles;
|
||||||
|
// if (shouldSaveObjectiveValuePlot) {
|
||||||
|
saveObjectiveValuePlot(saveToPath);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
csvFile csv_resultsLocalFile(std::filesystem::path(saveToPath).append("results.csv"),
|
||||||
|
true);
|
||||||
|
csv_resultsLocalFile << "Name";
|
||||||
|
writeHeaderTo(csv_resultsLocalFile);
|
||||||
|
settings.writeHeaderTo(csv_resultsLocalFile);
|
||||||
|
csv_resultsLocalFile << endrow;
|
||||||
|
csv_resultsLocalFile << baseTriangleFullPattern.getLabel();
|
||||||
|
writeResultsTo(csv_resultsLocalFile);
|
||||||
|
settings.writeSettingsTo(csv_resultsLocalFile);
|
||||||
|
csv_resultsLocalFile << endrow;
|
||||||
|
|
||||||
//save minima info
|
//save minima info
|
||||||
std::filesystem::path csvFilepathMinimaInfo = std::filesystem::path(saveToPath)
|
// std::filesystem::path csvFilepathMinimaInfo = std::filesystem::path(saveToPath)
|
||||||
.append("minimaInfo.csv");
|
// .append("minimaInfo.csv");
|
||||||
csvFile csv_minimaInfo(csvFilepathMinimaInfo, false);
|
// csvFile csv_minimaInfo(csvFilepathMinimaInfo, false);
|
||||||
writeMinimaInfoTo(csv_minimaInfo);
|
// writeMinimaInfoTo(csv_minimaInfo);
|
||||||
|
|
||||||
settings.save(saveToPath);
|
settings.save(saveToPath);
|
||||||
|
|
||||||
|
@ -707,6 +775,8 @@ struct Settings
|
||||||
std::ifstream ifs(std::filesystem::path(loadFromPath).append(DefaultFileName));
|
std::ifstream ifs(std::filesystem::path(loadFromPath).append(DefaultFileName));
|
||||||
ifs >> json_optimizationResults;
|
ifs >> json_optimizationResults;
|
||||||
|
|
||||||
|
// std::cout << json_optimizationResults.dump() << std::endl;
|
||||||
|
|
||||||
label = json_optimizationResults.at(JsonKeys::Label);
|
label = json_optimizationResults.at(JsonKeys::Label);
|
||||||
std::string optimizationVariablesString = *json_optimizationResults.find(
|
std::string optimizationVariablesString = *json_optimizationResults.find(
|
||||||
JsonKeys::optimizationVariables);
|
JsonKeys::optimizationVariables);
|
||||||
|
@ -732,8 +802,12 @@ struct Settings
|
||||||
|
|
||||||
const std::string fullPatternLabel = json_optimizationResults.at(
|
const std::string fullPatternLabel = json_optimizationResults.at(
|
||||||
JsonKeys::FullPatternLabel);
|
JsonKeys::FullPatternLabel);
|
||||||
baseTriangleFullPattern.load(
|
if (!baseTriangleFullPattern.load(
|
||||||
std::filesystem::path(loadFromPath).append(fullPatternLabel + ".ply").string());
|
std::filesystem::path(loadFromPath).append(fullPatternLabel + ".ply").string())) {
|
||||||
|
!baseTriangleFullPattern.load(std::filesystem::path(loadFromPath)
|
||||||
|
.append(loadFromPath.stem().string() + ".ply")
|
||||||
|
.string());
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<double> baseTriangleVertices = json_optimizationResults.at(
|
std::vector<double> baseTriangleVertices = json_optimizationResults.at(
|
||||||
JsonKeys::baseTriangle);
|
JsonKeys::baseTriangle);
|
||||||
|
@ -791,7 +865,7 @@ struct Settings
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename MeshType>
|
template<typename MeshType>
|
||||||
static void applyOptimizationResults_innerHexagon(
|
static void applyOptimizationResults_reducedModel_nonFanned(
|
||||||
const ReducedModelOptimization::Results &reducedPattern_optimizationResults,
|
const ReducedModelOptimization::Results &reducedPattern_optimizationResults,
|
||||||
const vcg::Triangle3<double> &patternBaseTriangle,
|
const vcg::Triangle3<double> &patternBaseTriangle,
|
||||||
MeshType &reducedPattern)
|
MeshType &reducedPattern)
|
||||||
|
@ -803,20 +877,20 @@ struct Settings
|
||||||
(optimalXVariables.contains("R") && optimalXVariables.contains("Theta"))
|
(optimalXVariables.contains("R") && optimalXVariables.contains("Theta"))
|
||||||
|| (optimalXVariables.contains("HexSize") && optimalXVariables.contains("HexAngle")));
|
|| (optimalXVariables.contains("HexSize") && optimalXVariables.contains("HexAngle")));
|
||||||
if (optimalXVariables.contains("HexSize")) {
|
if (optimalXVariables.contains("HexSize")) {
|
||||||
applyOptimizationResults_innerHexagon(optimalXVariables.at("HexSize"),
|
applyOptimizationResults_reducedModel_nonFanned(optimalXVariables.at("HexSize"),
|
||||||
optimalXVariables.at("HexAngle"),
|
optimalXVariables.at("HexAngle"),
|
||||||
patternBaseTriangle,
|
patternBaseTriangle,
|
||||||
reducedPattern);
|
reducedPattern);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
applyOptimizationResults_innerHexagon(optimalXVariables.at("R"),
|
applyOptimizationResults_reducedModel_nonFanned(optimalXVariables.at("R"),
|
||||||
optimalXVariables.at("Theta"),
|
optimalXVariables.at("Theta"),
|
||||||
patternBaseTriangle,
|
patternBaseTriangle,
|
||||||
reducedPattern);
|
reducedPattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename MeshType>
|
template<typename MeshType>
|
||||||
static void applyOptimizationResults_innerHexagon(
|
static void applyOptimizationResults_reducedModel_nonFanned(
|
||||||
const double &hexSize,
|
const double &hexSize,
|
||||||
const double &hexAngle,
|
const double &hexAngle,
|
||||||
const vcg::Triangle3<double> &patternBaseTriangle,
|
const vcg::Triangle3<double> &patternBaseTriangle,
|
||||||
|
|
|
@ -85,23 +85,6 @@ struct SimulationResultsReporter {
|
||||||
writeStatistics(simulationResult, simulationResultPath.string());
|
writeStatistics(simulationResult, simulationResultPath.string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void createPlot(const std::string &xLabel,
|
|
||||||
const std::string &yLabel,
|
|
||||||
const std::vector<double> &x,
|
|
||||||
const std::vector<double> &y,
|
|
||||||
const std::vector<double> &markerSizes,
|
|
||||||
const std::vector<double> &c,
|
|
||||||
const std::string &saveTo = {})
|
|
||||||
{
|
|
||||||
// matplot::figure(true);
|
|
||||||
matplot::xlabel(xLabel);
|
|
||||||
matplot::ylabel(yLabel);
|
|
||||||
matplot::grid(matplot::on);
|
|
||||||
matplot::scatter(x, y, markerSizes, c)->marker_face(true);
|
|
||||||
if (!saveTo.empty()) {
|
|
||||||
matplot::save(saveTo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void createPlot(const std::string &xLabel,
|
static void createPlot(const std::string &xLabel,
|
||||||
const std::string &yLabel,
|
const std::string &yLabel,
|
||||||
|
@ -121,7 +104,7 @@ struct SimulationResultsReporter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::vector<double> x = matplot::linspace(0, YvaluesToPlot.size() - 1, YvaluesToPlot.size());
|
std::vector<double> x = matplot::linspace(0, YvaluesToPlot.size() - 1, YvaluesToPlot.size());
|
||||||
createPlot(xLabel, yLabel, x, YvaluesToPlot, markerSizes, colors, saveTo);
|
Utilities::createPlot(xLabel, yLabel, x, YvaluesToPlot, markerSizes, colors, saveTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void createPlots(const SimulationHistory &history,
|
void createPlots(const SimulationHistory &history,
|
||||||
|
@ -178,10 +161,10 @@ struct SimulationResultsReporter {
|
||||||
// .append("ResidualForcesMovingAverageDerivativesLog_" + graphSuffix + ".png")
|
// .append("ResidualForcesMovingAverageDerivativesLog_" + graphSuffix + ".png")
|
||||||
// .string());
|
// .string());
|
||||||
// }
|
// }
|
||||||
if (!history.sumOfNormalizedDisplacementNorms.empty()) {
|
if (!history.perVertexAverageNormalizedDisplacementNorm.empty()) {
|
||||||
createPlot("Number of Iterations",
|
createPlot("Number of Iterations",
|
||||||
"Sum of normalized displacement norms",
|
"Sum of normalized displacement norms",
|
||||||
history.sumOfNormalizedDisplacementNorms,
|
history.perVertexAverageNormalizedDisplacementNorm,
|
||||||
std::filesystem::path(graphsFolder)
|
std::filesystem::path(graphsFolder)
|
||||||
.append("SumOfNormalizedDisplacementNorms_" + graphSuffix + ".png")
|
.append("SumOfNormalizedDisplacementNorms_" + graphSuffix + ".png")
|
||||||
.string(),
|
.string(),
|
||||||
|
|
|
@ -39,9 +39,12 @@ public:
|
||||||
std::vector<ElementMaterial> getBeamMaterial();
|
std::vector<ElementMaterial> getBeamMaterial();
|
||||||
|
|
||||||
double previousTotalKineticEnergy{0};
|
double previousTotalKineticEnergy{0};
|
||||||
|
double previousTranslationalKineticEnergy{0};
|
||||||
|
double previousTotalRotationalKineticEnergy{0};
|
||||||
double previousTotalResidualForcesNorm{0};
|
double previousTotalResidualForcesNorm{0};
|
||||||
double currentTotalKineticEnergy{0};
|
double currentTotalKineticEnergy{0};
|
||||||
double currentTotalTranslationalKineticEnergy{0};
|
double currentTotalTranslationalKineticEnergy{0};
|
||||||
|
double currentTotalRotationalKineticEnergy{0};
|
||||||
double totalResidualForcesNorm{0};
|
double totalResidualForcesNorm{0};
|
||||||
double totalExternalForcesNorm{0};
|
double totalExternalForcesNorm{0};
|
||||||
double averageResidualForcesNorm{0};
|
double averageResidualForcesNorm{0};
|
||||||
|
@ -49,7 +52,7 @@ public:
|
||||||
double previousTotalPotentialEnergykN{0};
|
double previousTotalPotentialEnergykN{0};
|
||||||
double residualForcesMovingAverageDerivativeNorm{0};
|
double residualForcesMovingAverageDerivativeNorm{0};
|
||||||
double residualForcesMovingAverage{0};
|
double residualForcesMovingAverage{0};
|
||||||
double sumOfNormalizedDisplacementNorms{0};
|
double perVertexAverageNormalizedDisplacementNorm{0};
|
||||||
bool save(const std::string &plyFilename = std::string());
|
bool save(const std::string &plyFilename = std::string());
|
||||||
void setBeamCrossSection(const CrossSectionType &beamDimensions);
|
void setBeamCrossSection(const CrossSectionType &beamDimensions);
|
||||||
void setBeamMaterial(const double &pr, const double &ym);
|
void setBeamMaterial(const double &pr, const double &ym);
|
||||||
|
@ -133,6 +136,7 @@ struct Node {
|
||||||
Vector6d internal{0};
|
Vector6d internal{0};
|
||||||
Vector6d residual{0};
|
Vector6d residual{0};
|
||||||
Vector6d internalAxial{0};
|
Vector6d internalAxial{0};
|
||||||
|
Vector6d internalTorsion{0};
|
||||||
Vector6d internalFirstBending{0};
|
Vector6d internalFirstBending{0};
|
||||||
Vector6d internalSecondBending{0};
|
Vector6d internalSecondBending{0};
|
||||||
bool hasExternalForce() const { return external.isZero(); }
|
bool hasExternalForce() const { return external.isZero(); }
|
||||||
|
|
|
@ -441,11 +441,12 @@ void TopologyEnumerator::computeValidPatterns(
|
||||||
// std::string previousPatternBinaryRepresentation(validEdges.size(),'0');
|
// std::string previousPatternBinaryRepresentation(validEdges.size(),'0');
|
||||||
size_t patternIndex = 0;
|
size_t patternIndex = 0;
|
||||||
bool validPatternsExist = false;
|
bool validPatternsExist = false;
|
||||||
const bool exportTilledPattern = true;
|
constexpr bool exportTilledPattern = false;
|
||||||
const bool saveCompressedFormat = false;
|
constexpr bool saveCompressedFormat = false;
|
||||||
do {
|
do {
|
||||||
patternIndex++;
|
patternIndex++;
|
||||||
const std::string patternName = std::to_string(patternIndex);
|
const std::string patternName = std::to_string(numberOfDesiredEdges) + "_"
|
||||||
|
+ std::to_string(patternIndex);
|
||||||
// std::cout << "Pattern name:" + patternBinaryRepresentation <<
|
// std::cout << "Pattern name:" + patternBinaryRepresentation <<
|
||||||
// std::endl; isValidPattern(patternBinaryRepresentation, validEdges,
|
// std::endl; isValidPattern(patternBinaryRepresentation, validEdges,
|
||||||
// numberOfDesiredEdges);
|
// numberOfDesiredEdges);
|
||||||
|
@ -465,6 +466,32 @@ void TopologyEnumerator::computeValidPatterns(
|
||||||
patternGeometry.add(allVertices, patternEdges);
|
patternGeometry.add(allVertices, patternEdges);
|
||||||
patternGeometry.setLabel(patternName);
|
patternGeometry.setLabel(patternName);
|
||||||
|
|
||||||
|
#ifdef POLYSCOPE_DEFINED
|
||||||
|
//1st example
|
||||||
|
// const bool shouldBreak = patternBinaryRepresentation == "00100000100100000"; //398
|
||||||
|
// const bool shouldBreak = patternBinaryRepresentation == "10000010101110110";//13036
|
||||||
|
// const bool shouldBreak = patternBinaryRepresentation == "00010111000010100"; //2481
|
||||||
|
// const bool shouldBreak = patternBinaryRepresentation == "10000101100110010"; //12116
|
||||||
|
// const bool shouldBreak = patternBinaryRepresentation == "10010111000000110"; //13915
|
||||||
|
//2nd example
|
||||||
|
// const bool shouldBreak = patternBinaryRepresentation == "00001011100010011"; //7_1203
|
||||||
|
// const bool shouldBreak = patternBinaryRepresentation == "00110001100100111"; //4865
|
||||||
|
// const bool shouldBreak = patternBinaryRepresentation == "00010000101000110"; //1380
|
||||||
|
// const bool shouldBreak = patternBinaryRepresentation == "00000010100010111"; //268
|
||||||
|
//3rd
|
||||||
|
// const bool shouldBreak = patternBinaryRepresentation == "10011011100000010"; //14272
|
||||||
|
// const bool shouldBreak = patternBinaryRepresentation == "10000111100110110"; //11877
|
||||||
|
// const bool shouldBreak = patternBinaryRepresentation == "00001011100010011"; //1203
|
||||||
|
// const bool shouldBreak = patternBinaryRepresentation == "00010101000110000"; //12117
|
||||||
|
|
||||||
|
// const bool shouldBreak = patternBinaryRepresentation == "10000101100110100"; //12117
|
||||||
|
// if (shouldBreak) {
|
||||||
|
// patternGeometry.registerForDrawing();
|
||||||
|
// polyscope::show();
|
||||||
|
// patternGeometry.unregister();
|
||||||
|
// }
|
||||||
|
#endif
|
||||||
|
|
||||||
// Check if pattern contains intersecting edges
|
// Check if pattern contains intersecting edges
|
||||||
const bool isInterfaceConnected = patternGeometry.isInterfaceConnected(interfaceNodes);
|
const bool isInterfaceConnected = patternGeometry.isInterfaceConnected(interfaceNodes);
|
||||||
// Export the tiled ply file if it contains intersecting edges
|
// Export the tiled ply file if it contains intersecting edges
|
||||||
|
|
|
@ -427,8 +427,9 @@ bool PatternGeometry::hasAngleSmallerThanThreshold(const std::vector<size_t> &nu
|
||||||
// (vert[vi].cP() + tiledIncidentVectors[tiledVectorIndex])[1],
|
// (vert[vi].cP() + tiledIncidentVectors[tiledVectorIndex])[1],
|
||||||
// (vert[vi].cP() + tiledIncidentVectors[tiledVectorIndex])[2]});
|
// (vert[vi].cP() + tiledIncidentVectors[tiledVectorIndex])[2]});
|
||||||
// }
|
// }
|
||||||
|
// polyscope::init();
|
||||||
// polyscope::registerCurveNetworkLine("temp", edgePoints);
|
// polyscope::registerCurveNetworkLine("temp", edgePoints);
|
||||||
// polyscope::show();
|
// polyscope::removeStructure("temp");
|
||||||
if (tiledIncidentVectors.size() == 1) {
|
if (tiledIncidentVectors.size() == 1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -440,14 +441,28 @@ bool PatternGeometry::hasAngleSmallerThanThreshold(const std::vector<size_t> &nu
|
||||||
[](const VectorType &v) { return vcg::Point2d(v[0], v[1]).Angle(); });
|
[](const VectorType &v) { return vcg::Point2d(v[0], v[1]).Angle(); });
|
||||||
//sort them using theta angles
|
//sort them using theta angles
|
||||||
std::sort(thetaAnglesOfIncidentVectors.begin(), thetaAnglesOfIncidentVectors.end());
|
std::sort(thetaAnglesOfIncidentVectors.begin(), thetaAnglesOfIncidentVectors.end());
|
||||||
|
// polyscope::show();
|
||||||
|
|
||||||
|
// std::vector<double> angles_theta(thetaAnglesOfIncidentVectors);
|
||||||
|
// for (double &theta_rad : angles_theta) {
|
||||||
|
// theta_rad = vcg::math::ToDeg(theta_rad);
|
||||||
|
// }
|
||||||
|
|
||||||
//find nodes that contain incident edges with relative angles less than the threshold
|
//find nodes that contain incident edges with relative angles less than the threshold
|
||||||
const double angleThreshold_rad = vcg::math::ToRad(angleThreshold_degrees);
|
const double angleThreshold_rad = vcg::math::ToRad(angleThreshold_degrees);
|
||||||
for (int thetaAngleIndex = 1; thetaAngleIndex < thetaAnglesOfIncidentVectors.size();
|
for (int thetaAngleIndex = 0; thetaAngleIndex < thetaAnglesOfIncidentVectors.size();
|
||||||
thetaAngleIndex++) {
|
thetaAngleIndex++) {
|
||||||
const double absAngleDifference = std::abs(
|
const auto &va_theta
|
||||||
thetaAnglesOfIncidentVectors[thetaAngleIndex]
|
= thetaAnglesOfIncidentVectors[(thetaAngleIndex + 1)
|
||||||
- thetaAnglesOfIncidentVectors[thetaAngleIndex - 1]);
|
% thetaAnglesOfIncidentVectors.size()];
|
||||||
|
const auto &vb_theta = thetaAnglesOfIncidentVectors[thetaAngleIndex];
|
||||||
|
// const auto &va
|
||||||
|
// = tiledIncidentVectors[(thetaAngleIndex + 1) % thetaAnglesOfIncidentVectors.size()];
|
||||||
|
// const auto &vb = tiledIncidentVectors[thetaAngleIndex];
|
||||||
|
const double absAngleDifference = std::abs(va_theta - vb_theta);
|
||||||
|
// const double debug_difDegOtherway = vcg::math::ToDeg(
|
||||||
|
// std::acos((va * vb) / (va.Norm() * vb.Norm())));
|
||||||
|
// const double debug_diffDeg = vcg::math::ToDeg(absAngleDifference);
|
||||||
if (absAngleDifference < angleThreshold_rad
|
if (absAngleDifference < angleThreshold_rad
|
||||||
/*&& absAngleDifference > vcg::math::ToRad(0.01)*/) {
|
/*&& absAngleDifference > vcg::math::ToRad(0.01)*/) {
|
||||||
// std::cout << "Found angDiff:" << absAngleDifference << std::endl;
|
// std::cout << "Found angDiff:" << absAngleDifference << std::endl;
|
||||||
|
@ -790,13 +805,17 @@ double PatternGeometry::computeBaseTriangleHeight() const
|
||||||
return vcg::Distance(vert[0].cP(), vert[interfaceNodeIndex].cP());
|
return vcg::Distance(vert[0].cP(), vert[interfaceNodeIndex].cP());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PatternGeometry::updateBaseTriangleHeight()
|
||||||
|
{
|
||||||
|
baseTriangleHeight = computeBaseTriangleHeight();
|
||||||
|
}
|
||||||
|
|
||||||
void PatternGeometry::deleteDanglingVertices()
|
void PatternGeometry::deleteDanglingVertices()
|
||||||
{
|
{
|
||||||
vcg::tri::Allocator<VCGEdgeMesh>::PointerUpdater<VertexPointer> pu;
|
vcg::tri::Allocator<VCGEdgeMesh>::PointerUpdater<VertexPointer> pu;
|
||||||
VCGEdgeMesh::deleteDanglingVertices(pu);
|
VCGEdgeMesh::deleteDanglingVertices(pu);
|
||||||
if (!pu.remap.empty()) {
|
if (!pu.remap.empty()) {
|
||||||
interfaceNodeIndex
|
interfaceNodeIndex = pu.remap[interfaceNodeIndex];
|
||||||
= pu.remap[interfaceNodeIndex]; //TODO:Could this be automatically be determined?
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -840,6 +859,8 @@ PatternGeometry::PatternGeometry(
|
||||||
addNormals();
|
addNormals();
|
||||||
baseTriangleHeight = computeBaseTriangleHeight();
|
baseTriangleHeight = computeBaseTriangleHeight();
|
||||||
baseTriangle = computeBaseTriangle();
|
baseTriangle = computeBaseTriangle();
|
||||||
|
vcg::tri::UpdateTopology<PatternGeometry>::VertexEdge(*this);
|
||||||
|
vcg::tri::UpdateTopology<PatternGeometry>::EdgeEdge(*this);
|
||||||
updateEigenEdgeAndVertices();
|
updateEigenEdgeAndVertices();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -914,6 +935,9 @@ std::shared_ptr<PatternGeometry> PatternGeometry::tilePattern(
|
||||||
fit->N() = faceNormal;
|
fit->N() = faceNormal;
|
||||||
PatternGeometry transformedPattern;
|
PatternGeometry transformedPattern;
|
||||||
transformedPattern.copy(pattern);
|
transformedPattern.copy(pattern);
|
||||||
|
// pattern.registerForDrawing();
|
||||||
|
// polyscope::show();
|
||||||
|
// pattern.unregister();
|
||||||
//Transform the base triangle nodes to the mesh triangle using barycentric coords
|
//Transform the base triangle nodes to the mesh triangle using barycentric coords
|
||||||
for (int vi = 0; vi < transformedPattern.VN(); vi++) {
|
for (int vi = 0; vi < transformedPattern.VN(); vi++) {
|
||||||
transformedPattern.vert[vi].P() = CoordType(
|
transformedPattern.vert[vi].P() = CoordType(
|
||||||
|
@ -933,6 +957,10 @@ std::shared_ptr<PatternGeometry> PatternGeometry::tilePattern(
|
||||||
for (size_t ei = 0; ei < pattern.EN(); ei++) {
|
for (size_t ei = 0; ei < pattern.EN(); ei++) {
|
||||||
perPatternIndexToTiledPatternEdgeIndex[patternIndex].push_back(remap.edge[ei]);
|
perPatternIndexToTiledPatternEdgeIndex[patternIndex].push_back(remap.edge[ei]);
|
||||||
}
|
}
|
||||||
|
// pTiledPattern->registerForDrawing();
|
||||||
|
// pTiledPattern->markVertices({remap.vert[pattern.interfaceNodeIndex]});
|
||||||
|
// polyscope::show();
|
||||||
|
// pTiledPattern->unregister();
|
||||||
const size_t ei = tileInto.getIndex(ep);
|
const size_t ei = tileInto.getIndex(ep);
|
||||||
tileIntoEdgeToInterfaceVi[ei].push_back(remap.vert[pattern.interfaceNodeIndex]);
|
tileIntoEdgeToInterfaceVi[ei].push_back(remap.vert[pattern.interfaceNodeIndex]);
|
||||||
//Add edges for connecting the desired vertices
|
//Add edges for connecting the desired vertices
|
||||||
|
@ -965,10 +993,6 @@ std::shared_ptr<PatternGeometry> PatternGeometry::tilePattern(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// pTiledPattern->updateEigenEdgeAndVertices();
|
|
||||||
// pTiledPattern->registerForDrawing();
|
|
||||||
|
|
||||||
// polyscope::show();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vcg::tri::Allocator<VCGEdgeMesh>::PointerUpdater<VertexPointer> pu_vertices;
|
vcg::tri::Allocator<VCGEdgeMesh>::PointerUpdater<VertexPointer> pu_vertices;
|
||||||
|
@ -987,6 +1011,7 @@ std::shared_ptr<PatternGeometry> PatternGeometry::tilePattern(
|
||||||
|
|
||||||
// tiledPatternEdges.erase(end, tiledPatternEdges.end());
|
// tiledPatternEdges.erase(end, tiledPatternEdges.end());
|
||||||
// }
|
// }
|
||||||
|
|
||||||
const size_t sumOfEdgeIndices = std::accumulate(perPatternIndexToTiledPatternEdgeIndex.begin(),
|
const size_t sumOfEdgeIndices = std::accumulate(perPatternIndexToTiledPatternEdgeIndex.begin(),
|
||||||
perPatternIndexToTiledPatternEdgeIndex.end(),
|
perPatternIndexToTiledPatternEdgeIndex.end(),
|
||||||
0,
|
0,
|
||||||
|
@ -1017,7 +1042,7 @@ std::shared_ptr<PatternGeometry> PatternGeometry::tilePattern(
|
||||||
pTiledPattern->deleteDanglingVertices();
|
pTiledPattern->deleteDanglingVertices();
|
||||||
vcg::tri::Allocator<PatternGeometry>::CompactEveryVector(*pTiledPattern);
|
vcg::tri::Allocator<PatternGeometry>::CompactEveryVector(*pTiledPattern);
|
||||||
pTiledPattern->updateEigenEdgeAndVertices();
|
pTiledPattern->updateEigenEdgeAndVertices();
|
||||||
pTiledPattern->save();
|
// pTiledPattern->save();
|
||||||
return pTiledPattern;
|
return pTiledPattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1078,17 +1103,21 @@ void PatternGeometry::copy(PatternGeometry ©From)
|
||||||
interfaceNodeIndex = copyFrom.interfaceNodeIndex;
|
interfaceNodeIndex = copyFrom.interfaceNodeIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PatternGeometry::scale(const double &desiredBaseTriangleCentralEdgeSize,
|
void PatternGeometry::scale(const double &desiredBaseTriangleCentralEdgeSize)
|
||||||
const int &interfaceNodeIndex)
|
|
||||||
{
|
{
|
||||||
const double baseTriangleCentralEdgeSize = computeBaseTriangleHeight();
|
const double baseTriangleCentralEdgeSize = getBaseTriangleHeight();
|
||||||
const double scaleRatio = desiredBaseTriangleCentralEdgeSize / baseTriangleCentralEdgeSize;
|
const double scaleRatio = desiredBaseTriangleCentralEdgeSize / baseTriangleCentralEdgeSize;
|
||||||
vcg::tri::UpdatePosition<VCGEdgeMesh>::Scale(*this, scaleRatio);
|
vcg::tri::UpdatePosition<VCGEdgeMesh>::Scale(*this, scaleRatio);
|
||||||
baseTriangle = computeBaseTriangle();
|
baseTriangle = computeBaseTriangle();
|
||||||
baseTriangleHeight = computeBaseTriangleHeight();
|
baseTriangleHeight = computeBaseTriangleHeight();
|
||||||
|
const double debug_baseTriHeight = vcg::Distance(baseTriangle.cP(0),
|
||||||
|
(baseTriangle.cP(1) + baseTriangle.cP(2)) / 2);
|
||||||
|
assert(std::abs(desiredBaseTriangleCentralEdgeSize - baseTriangleHeight) < 1e-10);
|
||||||
|
int i = 0;
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PatternGeometry::createFan(const std::vector<int> &connectToNeighborsVi, const size_t &fanSize)
|
void PatternGeometry::createFan(const size_t &fanSize)
|
||||||
{
|
{
|
||||||
PatternGeometry rotatedPattern;
|
PatternGeometry rotatedPattern;
|
||||||
vcg::tri::Append<PatternGeometry, PatternGeometry>::MeshCopy(rotatedPattern, *this);
|
vcg::tri::Append<PatternGeometry, PatternGeometry>::MeshCopy(rotatedPattern, *this);
|
||||||
|
@ -1099,28 +1128,6 @@ void PatternGeometry::createFan(const std::vector<int> &connectToNeighborsVi, co
|
||||||
vcg::tri::UpdatePosition<PatternGeometry>::Matrix(rotatedPattern, R);
|
vcg::tri::UpdatePosition<PatternGeometry>::Matrix(rotatedPattern, R);
|
||||||
vcg::tri::Append<PatternGeometry, PatternGeometry>::Mesh(*this, rotatedPattern);
|
vcg::tri::Append<PatternGeometry, PatternGeometry>::Mesh(*this, rotatedPattern);
|
||||||
//Add edges for connecting the desired vertices
|
//Add edges for connecting the desired vertices
|
||||||
if (!connectToNeighborsVi.empty()) {
|
|
||||||
if (rotationCounter == fanSize - 1) {
|
|
||||||
for (int connectToNeighborIndex = 0;
|
|
||||||
connectToNeighborIndex < connectToNeighborsVi.size();
|
|
||||||
connectToNeighborIndex++) {
|
|
||||||
vcg::tri::Allocator<PatternGeometry>::AddEdge(
|
|
||||||
*this,
|
|
||||||
connectToNeighborsVi[connectToNeighborIndex],
|
|
||||||
this->VN() - rotatedPattern.VN()
|
|
||||||
+ connectToNeighborsVi[connectToNeighborIndex]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int connectToNeighborIndex = 0;
|
|
||||||
connectToNeighborIndex < connectToNeighborsVi.size();
|
|
||||||
connectToNeighborIndex++) {
|
|
||||||
vcg::tri::Allocator<PatternGeometry>::AddEdge(
|
|
||||||
*this,
|
|
||||||
this->VN() - 2 * rotatedPattern.VN()
|
|
||||||
+ connectToNeighborsVi[connectToNeighborIndex],
|
|
||||||
this->VN() - rotatedPattern.VN() + connectToNeighborsVi[connectToNeighborIndex]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
removeDuplicateVertices();
|
removeDuplicateVertices();
|
||||||
updateEigenEdgeAndVertices();
|
updateEigenEdgeAndVertices();
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@ private:
|
||||||
|
|
||||||
void addNormals();
|
void addNormals();
|
||||||
double baseTriangleHeight;
|
double baseTriangleHeight;
|
||||||
double computeBaseTriangleHeight() const;
|
|
||||||
|
|
||||||
inline static size_t fanSize{6};
|
inline static size_t fanSize{6};
|
||||||
std::vector<VCGEdgeMesh::CoordType> vertices;
|
std::vector<VCGEdgeMesh::CoordType> vertices;
|
||||||
|
@ -95,20 +94,23 @@ private:
|
||||||
const int &interfaceNodeIndex,
|
const int &interfaceNodeIndex,
|
||||||
const bool &shouldDeleteDanglingEdges);
|
const bool &shouldDeleteDanglingEdges);
|
||||||
|
|
||||||
void scale(const double &desiredBaseTriangleCentralEdgeSize, const int &interfaceNodeIndex);
|
void scale(const double &desiredBaseTriangleCentralEdgeSize);
|
||||||
|
|
||||||
double getBaseTriangleHeight() const;
|
double getBaseTriangleHeight() const;
|
||||||
vcg::Triangle3<double> computeBaseTriangle() const;
|
vcg::Triangle3<double> computeBaseTriangle() const;
|
||||||
|
void updateBaseTriangle();
|
||||||
|
double computeBaseTriangleHeight() const;
|
||||||
|
void updateBaseTriangleHeight();
|
||||||
|
|
||||||
PatternGeometry(const std::vector<vcg::Point2d> &vertices, const std::vector<vcg::Point2i> &edges);
|
// PatternGeometry(const std::vector<vcg::Point2d> &vertices, const std::vector<vcg::Point2i> &edges);
|
||||||
// static std::shared_ptr<PatternGeometry> tilePattern(
|
// static std::shared_ptr<PatternGeometry> tilePattern(
|
||||||
// std::vector<PatternGeometry> &pattern,
|
// std::vector<PatternGeometry> &pattern,
|
||||||
// const std::vector<int> &connectToNeighborsVi,
|
// const std::vector<int> &connectToNeighborsVi,
|
||||||
// const VCGPolyMesh &tileInto,
|
// const VCGPolyMesh &tileInto,
|
||||||
// std::vector<int> &tileIntoEdgesToTiledVi,
|
// std::vector<int> &tileIntoEdgesToTiledVi,
|
||||||
// std::vector<std::vector<size_t>> &perPatternEdges);
|
// std::vector<std::vector<size_t>> &perPatternEdges);
|
||||||
void createFan(const std::vector<int> &connectToNeighborsVi = std::vector<int>(),
|
virtual void createFan(/*const std::vector<int> &connectToNeighborsVi = std::vector<int>(),*/
|
||||||
const size_t &fanSize = 6);
|
const size_t &fanSize = 6);
|
||||||
int interfaceNodeIndex{3}; //TODO: Fix this. This should be automatically computed
|
int interfaceNodeIndex{3}; //TODO: Fix this. This should be automatically computed
|
||||||
bool hasAngleSmallerThanThreshold(const std::vector<size_t> &numberOfNodesPerSlot,
|
bool hasAngleSmallerThanThreshold(const std::vector<size_t> &numberOfNodesPerSlot,
|
||||||
const double &angleThreshold_degrees);
|
const double &angleThreshold_degrees);
|
||||||
|
@ -129,7 +131,6 @@ private:
|
||||||
void deleteDanglingVertices() override;
|
void deleteDanglingVertices() override;
|
||||||
void deleteDanglingVertices(
|
void deleteDanglingVertices(
|
||||||
vcg::tri::Allocator<VCGEdgeMesh>::PointerUpdater<VertexPointer> &pu) override;
|
vcg::tri::Allocator<VCGEdgeMesh>::PointerUpdater<VertexPointer> &pu) override;
|
||||||
void updateBaseTriangle();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FLATPATTERNGEOMETRY_HPP
|
#endif // FLATPATTERNGEOMETRY_HPP
|
||||||
|
|
Loading…
Reference in New Issue