2020-11-23 10:06:45 +01:00
|
|
|
#include "beamformfinder.hpp"
|
2021-01-22 15:39:36 +01:00
|
|
|
#include "csvfile.hpp"
|
2020-11-23 10:06:45 +01:00
|
|
|
#include "edgemesh.hpp"
|
|
|
|
#include "flatpattern.hpp"
|
|
|
|
#include "polyscope/curve_network.h"
|
|
|
|
#include "polyscope/point_cloud.h"
|
|
|
|
#include "polyscope/polyscope.h"
|
|
|
|
#include "reducedmodeloptimizer.hpp"
|
|
|
|
#include "simulationhistoryplotter.hpp"
|
2020-12-09 16:58:48 +01:00
|
|
|
#include "trianglepattterntopology.hpp"
|
2020-11-23 10:06:45 +01:00
|
|
|
#include <chrono>
|
|
|
|
#include <filesystem>
|
|
|
|
#include <iostream>
|
2021-02-01 15:10:24 +01:00
|
|
|
#include <iterator>
|
2020-11-23 10:06:45 +01:00
|
|
|
#include <stdexcept>
|
|
|
|
#include <string>
|
2020-12-09 16:58:48 +01:00
|
|
|
#include <vcg/complex/algorithms/update/position.h>
|
|
|
|
|
2021-02-18 11:12:52 +01:00
|
|
|
void exportOptimizationResults(
|
|
|
|
const ReducedModelOptimizer::Results &optimizationResults,
|
|
|
|
const std::filesystem::path &optimizationDirectory,
|
|
|
|
const ReducedModelOptimizer::Settings &settings_optimization,
|
|
|
|
csvFile &statistics,
|
|
|
|
const std::pair<FlatPattern *, FlatPattern *> patternPair) {
|
|
|
|
std::filesystem::path saveToPath(std::filesystem::path(optimizationDirectory)
|
|
|
|
.append(patternPair.first->getLabel() +
|
|
|
|
"@" +
|
|
|
|
patternPair.second->getLabel()));
|
|
|
|
std::filesystem::create_directories(std::filesystem::path(saveToPath));
|
2021-02-14 13:27:14 +01:00
|
|
|
|
2021-02-18 11:12:52 +01:00
|
|
|
optimizationResults.save(saveToPath.string());
|
|
|
|
statistics << patternPair.first->getLabel() + "@" +
|
|
|
|
patternPair.second->getLabel();
|
|
|
|
statistics << optimizationResults.objectiveValue;
|
|
|
|
for (const double &optimalX : optimizationResults.x) {
|
|
|
|
statistics << optimalX;
|
|
|
|
}
|
2021-02-14 13:27:14 +01:00
|
|
|
|
2021-02-18 11:12:52 +01:00
|
|
|
for (int unusedXVarCounter = 0;
|
|
|
|
unusedXVarCounter <
|
|
|
|
settings_optimization.xRanges.size() - optimizationResults.x.size();
|
|
|
|
unusedXVarCounter++) {
|
|
|
|
statistics << "-";
|
|
|
|
}
|
2021-02-14 13:27:14 +01:00
|
|
|
|
2021-02-18 11:12:52 +01:00
|
|
|
statistics << optimizationResults.time;
|
|
|
|
if (optimizationResults.numberOfSimulationCrashes == 0) {
|
|
|
|
statistics << "No crashes";
|
|
|
|
} else {
|
|
|
|
statistics << optimizationResults.numberOfSimulationCrashes;
|
|
|
|
}
|
|
|
|
statistics << endrow;
|
2021-02-14 13:27:14 +01:00
|
|
|
}
|
|
|
|
|
2021-02-18 11:12:52 +01:00
|
|
|
void optimizeTestSet(
|
|
|
|
const std::vector<std::pair<FlatPattern *, FlatPattern *>> patternPairs,
|
|
|
|
const ReducedModelOptimizer::Settings &settings_optimization,
|
|
|
|
const std::string &saveTo) {
|
2021-02-14 13:27:14 +01:00
|
|
|
const std::string optimizationSettingsString =
|
|
|
|
settings_optimization.toString();
|
|
|
|
std::filesystem::path thisOptimizationDirectory(
|
2021-02-18 11:12:52 +01:00
|
|
|
std::filesystem::path(saveTo).append(optimizationSettingsString));
|
|
|
|
//.append("Results"));
|
2021-02-14 13:27:14 +01:00
|
|
|
std::filesystem::create_directories(thisOptimizationDirectory);
|
|
|
|
std::cout << optimizationSettingsString << std::endl;
|
|
|
|
csvFile csv_settings(std::filesystem::path(thisOptimizationDirectory)
|
|
|
|
.append("settings.csv")
|
|
|
|
.string(),
|
|
|
|
true);
|
|
|
|
settings_optimization.writeTo(csv_settings);
|
|
|
|
csvFile statistics(std::filesystem::path(thisOptimizationDirectory)
|
|
|
|
.append("statistics.csv")
|
|
|
|
.string(),
|
|
|
|
false);
|
|
|
|
|
|
|
|
// Write header to csv
|
|
|
|
statistics << "FullPattern@ReducedPattern"
|
|
|
|
<< "Obj value";
|
|
|
|
for (const ReducedModelOptimizer::xRange &range :
|
|
|
|
settings_optimization.xRanges) {
|
|
|
|
statistics << range.label;
|
|
|
|
}
|
|
|
|
statistics << "Time(s)";
|
|
|
|
statistics << "#Crashes";
|
|
|
|
statistics << endrow;
|
|
|
|
|
|
|
|
double totalError = 0;
|
|
|
|
int totalNumberOfSimulationCrashes = 0;
|
|
|
|
std::vector<ReducedModelOptimizer::Results> optimizationResults_testSet(
|
|
|
|
patternPairs.size());
|
|
|
|
auto start = std::chrono::high_resolution_clock::now();
|
2021-02-18 11:12:52 +01:00
|
|
|
int pairsOptimized = 0;
|
|
|
|
#pragma omp parallel for
|
2021-02-14 13:27:14 +01:00
|
|
|
for (int patternPairIndex = 0; patternPairIndex < patternPairs.size();
|
2021-02-18 11:12:52 +01:00
|
|
|
patternPairIndex++) {
|
|
|
|
const std::pair<FlatPattern *, FlatPattern *> &patternPair =
|
|
|
|
patternPairs[patternPairIndex];
|
|
|
|
std::cout << "Optimizing " << patternPair.first->getLabel() << "@"
|
|
|
|
<< patternPair.second->getLabel() << std::endl;
|
|
|
|
const std::vector<size_t> numberOfNodesPerSlot{1, 0, 0, 2, 1, 2, 1};
|
|
|
|
ReducedModelOptimizer optimizer(numberOfNodesPerSlot);
|
|
|
|
optimizer.initializePatterns(*patternPair.first, *patternPair.second, {});
|
|
|
|
ReducedModelOptimizer::Results optimizationResults =
|
|
|
|
optimizer.optimize(settings_optimization);
|
2021-02-14 13:27:14 +01:00
|
|
|
|
2021-02-18 11:12:52 +01:00
|
|
|
totalError += optimizationResults.objectiveValue;
|
|
|
|
optimizationResults_testSet[patternPairIndex] = optimizationResults;
|
|
|
|
totalNumberOfSimulationCrashes +=
|
|
|
|
optimizationResults.numberOfSimulationCrashes;
|
|
|
|
|
|
|
|
std::cout << "Optimized " << ++pairsOptimized << "/" << patternPairs.size()
|
|
|
|
<< std::endl;
|
|
|
|
#pragma omp critical
|
|
|
|
{
|
|
|
|
exportOptimizationResults(optimizationResults, thisOptimizationDirectory,
|
|
|
|
settings_optimization, statistics, patternPair);
|
|
|
|
optimizationResults.draw();
|
|
|
|
}
|
2021-02-14 13:27:14 +01:00
|
|
|
}
|
2021-02-18 11:12:52 +01:00
|
|
|
|
|
|
|
// for (int patternPairIndex = 0; patternPairIndex < patternPairs.size();
|
|
|
|
// patternPairIndex++) {
|
|
|
|
// const std::pair<FlatPattern *, FlatPattern *> &patternPair =
|
|
|
|
// patternPairs[patternPairIndex];
|
|
|
|
// const ReducedModelOptimizer::Results optimizationResults =
|
|
|
|
// optimizationResults_testSet[patternPairIndex];
|
|
|
|
// // Save results
|
|
|
|
// std::filesystem::path saveToPath(
|
|
|
|
// std::filesystem::path(thisOptimizationDirectory)
|
|
|
|
// .append(patternPair.first->getLabel() + "@" +
|
|
|
|
// patternPair.second->getLabel()));
|
|
|
|
// std::filesystem::create_directories(std::filesystem::path(saveToPath));
|
|
|
|
// optimizationResults.save(saveToPath.string());
|
|
|
|
|
|
|
|
// // Save statistics
|
|
|
|
// statistics << patternPair.first->getLabel() + "@" +
|
|
|
|
// patternPair.second->getLabel();
|
|
|
|
// statistics << optimizationResults.objectiveValue;
|
|
|
|
// for (const double &optimalX : optimizationResults.x) {
|
|
|
|
// statistics << optimalX;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// for (int unusedXVarCounter = 0;
|
|
|
|
// unusedXVarCounter <
|
|
|
|
// settings_optimization.xRanges.size() -
|
|
|
|
// optimizationResults.x.size(); unusedXVarCounter++) {
|
|
|
|
// statistics << "-";
|
|
|
|
// }
|
|
|
|
|
|
|
|
// statistics << optimizationResults.time;
|
|
|
|
// if (optimizationResults.numberOfSimulationCrashes == 0) {
|
|
|
|
// statistics << "No crashes";
|
|
|
|
// } else {
|
|
|
|
// statistics << optimizationResults.numberOfSimulationCrashes;
|
|
|
|
// }
|
|
|
|
// statistics << endrow;
|
|
|
|
// }
|
2021-02-14 13:27:14 +01:00
|
|
|
}
|
|
|
|
|
2020-11-23 10:06:45 +01:00
|
|
|
int main(int argc, char *argv[]) {
|
2020-11-27 11:45:20 +01:00
|
|
|
// Create reduced models
|
2020-12-16 20:31:58 +01:00
|
|
|
// FormFinder::runUnitTests();
|
2020-11-27 11:45:20 +01:00
|
|
|
const std::vector<size_t> numberOfNodesPerSlot{1, 0, 0, 2, 1, 2, 1};
|
|
|
|
std::vector<vcg::Point2i> singleBarReducedModelEdges{vcg::Point2i(0, 3)};
|
|
|
|
FlatPattern singleBarReducedModel(numberOfNodesPerSlot,
|
|
|
|
singleBarReducedModelEdges);
|
2021-02-04 15:05:48 +01:00
|
|
|
singleBarReducedModel.setLabel("SingleBar_reduced");
|
2021-02-18 11:12:52 +01:00
|
|
|
singleBarReducedModel.savePly(singleBarReducedModel.getLabel());
|
2020-12-22 17:47:29 +01:00
|
|
|
singleBarReducedModel.scale(0.03);
|
2020-11-27 11:45:20 +01:00
|
|
|
|
2020-12-14 10:07:43 +01:00
|
|
|
std::vector<vcg::Point2i> CWreducedModelEdges{vcg::Point2i(1, 5),
|
2021-02-18 11:12:52 +01:00
|
|
|
vcg::Point2i(3, 5)};
|
2020-12-22 17:47:29 +01:00
|
|
|
FlatPattern CWReducedModel(numberOfNodesPerSlot, CWreducedModelEdges);
|
2021-02-18 11:12:52 +01:00
|
|
|
CWReducedModel.setLabel("CW_reduced");
|
2020-12-22 17:47:29 +01:00
|
|
|
CWReducedModel.scale(0.03);
|
|
|
|
|
|
|
|
std::vector<vcg::Point2i> CCWreducedModelEdges{vcg::Point2i(1, 5),
|
2021-02-18 11:12:52 +01:00
|
|
|
vcg::Point2i(3, 1)};
|
2020-12-22 17:47:29 +01:00
|
|
|
FlatPattern CCWReducedModel(numberOfNodesPerSlot, CCWreducedModelEdges);
|
2021-02-18 11:12:52 +01:00
|
|
|
CCWReducedModel.setLabel("CCW_reduced");
|
|
|
|
CCWReducedModel.savePly(CWReducedModel.getLabel());
|
2020-12-22 17:47:29 +01:00
|
|
|
CCWReducedModel.scale(0.03);
|
2020-11-27 11:45:20 +01:00
|
|
|
|
2020-12-14 10:07:43 +01:00
|
|
|
std::vector<FlatPattern *> reducedModels{&singleBarReducedModel,
|
|
|
|
&CWReducedModel, &CCWReducedModel};
|
2020-11-27 11:45:20 +01:00
|
|
|
|
2021-02-04 15:05:48 +01:00
|
|
|
// Define the ranges that the optimizer will use
|
|
|
|
ReducedModelOptimizer::xRange beamWidth{"B", 0.5, 1.5};
|
|
|
|
ReducedModelOptimizer::xRange beamDimensionsRatio{"bOverh", 0.7, 1.3};
|
|
|
|
ReducedModelOptimizer::xRange beamE{"E", 0.1, 1.9};
|
2021-02-14 13:27:14 +01:00
|
|
|
ReducedModelOptimizer::xRange innerHexagonSize{"HS", 0.1, 0.9};
|
2021-02-01 15:10:24 +01:00
|
|
|
// Test set of full patterns
|
2021-02-18 11:12:52 +01:00
|
|
|
std::string fullPatternsTestSetDirectory = "../TestSet";
|
2021-02-09 20:43:49 +01:00
|
|
|
if (!std::filesystem::exists(
|
|
|
|
std::filesystem::path(fullPatternsTestSetDirectory))) {
|
|
|
|
std::cerr << "Full pattern directory does not exist: "
|
|
|
|
<< fullPatternsTestSetDirectory << std::endl;
|
|
|
|
return 1;
|
|
|
|
}
|
2021-02-01 15:10:24 +01:00
|
|
|
// "/home/iason/Documents/PhD/Research/Approximating shapes with flat "
|
|
|
|
// "patterns/Pattern_enumerator/Results/1v_0v_2e_1e_1c_6fan/3/Valid";
|
|
|
|
std::vector<std::pair<FlatPattern *, FlatPattern *>> patternPairs;
|
|
|
|
for (const auto &entry :
|
|
|
|
filesystem::directory_iterator(fullPatternsTestSetDirectory)) {
|
|
|
|
const auto filepath =
|
|
|
|
// std::filesystem::path(fullPatternsTestSetDirectory).append("305.ply");
|
|
|
|
entry.path();
|
|
|
|
const std::string filepathString = filepath.string();
|
|
|
|
const std::string tiledSuffix = "_tiled.ply";
|
|
|
|
if (filepathString.compare(filepathString.size() - tiledSuffix.size(),
|
|
|
|
tiledSuffix.size(), tiledSuffix) == 0) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-02-12 17:09:56 +01:00
|
|
|
FlatPattern fullPattern(filepathString);
|
2021-02-18 11:12:52 +01:00
|
|
|
fullPattern.setLabel(filepath.stem().string());
|
|
|
|
fullPattern.scale(0.03);
|
|
|
|
// for (int reducedPatternIndex = 0;
|
|
|
|
// reducedPatternIndex < reducedModels.size();
|
|
|
|
// reducedPatternIndex++) {
|
|
|
|
FlatPattern *pFullPattern = new FlatPattern();
|
|
|
|
pFullPattern->copy(fullPattern);
|
|
|
|
FlatPattern *pReducedPattern = new FlatPattern();
|
|
|
|
// pReducedPattern->copy(*reducedModels[reducedPatternIndex]);
|
|
|
|
pReducedPattern->copy(*reducedModels[0]);
|
|
|
|
patternPairs.push_back(std::make_pair(pFullPattern, pReducedPattern));
|
|
|
|
// }
|
2021-02-01 15:10:24 +01:00
|
|
|
}
|
|
|
|
|
2021-01-29 18:07:13 +01:00
|
|
|
// for (double rangeOffset = 0.15; rangeOffset <= 0.95; rangeOffset += 0.05)
|
|
|
|
// {
|
2021-02-10 12:19:37 +01:00
|
|
|
ReducedModelOptimizer::Settings settings_optimization;
|
|
|
|
settings_optimization.xRanges = {beamWidth, beamDimensionsRatio, beamE,
|
|
|
|
innerHexagonSize};
|
|
|
|
|
|
|
|
// for (settings_optimization.numberOfFunctionCalls = 100;
|
|
|
|
// settings_optimization.numberOfFunctionCalls < 5000;
|
|
|
|
// settings_optimization.numberOfFunctionCalls += 100) {
|
2021-02-14 13:27:14 +01:00
|
|
|
std::string optimiziationResultsDirectory = "OptimizationResults";
|
|
|
|
if (argc < 2) {
|
2021-02-18 11:12:52 +01:00
|
|
|
settings_optimization.numberOfFunctionCalls = 100;
|
|
|
|
} else if (argc == 2) {
|
|
|
|
settings_optimization.numberOfFunctionCalls = std::atoi(argv[1]);
|
|
|
|
} else if (argc == 3) {
|
|
|
|
settings_optimization.numberOfFunctionCalls = std::atoi(argv[1]);
|
|
|
|
optimiziationResultsDirectory = argv[2];
|
2021-02-10 12:19:37 +01:00
|
|
|
}
|
2021-02-18 11:12:52 +01:00
|
|
|
// settings_optimization.normalizeObjectiveValue = false;
|
|
|
|
// optimizeTestSet(patternPairs, settings_optimization,
|
|
|
|
// optimiziationResultsDirectory);
|
2021-02-14 13:27:14 +01:00
|
|
|
settings_optimization.normalizeObjectiveValue = true;
|
2021-02-18 11:12:52 +01:00
|
|
|
optimizeTestSet(patternPairs, settings_optimization,
|
|
|
|
optimiziationResultsDirectory);
|
2021-02-04 15:05:48 +01:00
|
|
|
|
2021-02-14 13:27:14 +01:00
|
|
|
for (auto &patternPair : patternPairs) {
|
2021-02-04 15:05:48 +01:00
|
|
|
delete patternPair.first;
|
|
|
|
delete patternPair.second;
|
|
|
|
}
|
2020-11-23 10:06:45 +01:00
|
|
|
return 0;
|
|
|
|
}
|