From 02295c4ba5f79ab7c8896d83f0b5963cf687017f Mon Sep 17 00:00:00 2001 From: iasonmanolas Date: Mon, 12 Jul 2021 23:30:23 +0300 Subject: [PATCH] Saving force magnitudes --- src/main.cpp | 62 ++- src/reducedpatternsimulator.cpp | 762 +++++++++++++++++++++++++------- src/reducedpatternsimulator.hpp | 92 ++-- 3 files changed, 704 insertions(+), 212 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 51d6364..9a3095b 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,26 +11,52 @@ int main(int argc, char *argv[]) { - // DRMSimulationModel::runUnitTests(); + if (argc != 3) { + return 1; + } + // DRMSimulationModel::runUnitTests(); + // const std::string tileInto_triMesh_filename("/home/iason/Models/" + // "hexagon_384tri.ply"); + const std::string tileInto_triMesh_filename = argv[1]; + // const std::string tileInto_triMesh_filename( + // "/home/iason/Coding/build/PatternTillingReducedModel/Meshes/fra/ex5_56.ply"); + // const std::string tileInto_triMesh_filename( + // "/home/iason/Coding/build/PatternTillingReducedModel/Meshes/fra/ex3_96.ply"); + // const std::string tileInto_triMesh_filename( + // "/home/iason/Coding/build/PatternTillingReducedModel/Meshes/fra/ex2_230.ply"); + // const std::string tileInto_triMesh_filename( + // "/home/iason/Coding/build/PatternTillingReducedModel/Meshes/fra/ex1_74.ply"); + // const std::string tileInto_triMesh_filename( + // "/home/iason/Coding/build/PatternTillingReducedModel/Meshes/fra/ex2_122.ply"); + // const std::string tileInto_triMesh_filename( + // "/home/iason/Coding/build/PatternTillingReducedModel/Meshes/" + // "instantMeshes_plane_200_big_1x1_100x100.ply"); + // const std::string tileInto_triMesh_filename( + // "/home/iason/Coding/build/PatternTillingReducedModel/Meshes/" + // "instantMeshes_plane_500_big_1x1_100x100.ply"); + // const std::string tileInto_triMesh_filename( + // "/home/iason/Coding/build/PatternTillingReducedModel/Meshes/" + // "instantMeshes_plane_1000_big_1x1_100x100.ply"); // const std::string tileInto_triMesh_filename( // "/home/iason/Coding/build/PatternTillingReducedModel/Meshes/" // "instantMeshes_strip_45.ply"); // const std::string tileInto_triMesh_filename( // "/home/iason/Coding/build/PatternTillingReducedModel/Meshes/" // "instantMeshes_widerStrip_100.ply"); - const std::string tileInto_triMesh_filename( - "/home/iason/Coding/build/PatternTillingReducedModel/Meshes/" - "instantMeshes_plane_34.ply"); + // const std::string tileInto_triMesh_filename( + // "/home/iason/Coding/build/PatternTillingReducedModel/Meshes/" + // "instantMeshes_plane_34.ply"); // const std::string tileInto_triMesh_filename( // "/home/iason/Coding/build/PatternTillingReducedModel/RelWithDebInfo/" // "instantMeshes_plane4Hexagon_5.ply"); VCGTriMesh tileInto_triMesh; - tileInto_triMesh.load(tileInto_triMesh_filename); + const bool surfaceLoadSuccessfull = tileInto_triMesh.load(tileInto_triMesh_filename); + assert(surfaceLoadSuccessfull); std::shared_ptr pTileInto_polyMesh = PolygonalRemeshing::remeshWithPolygons( tileInto_triMesh); - //Load optimization results + // //Load optimization results // const size_t numberOfOptimizationResults = argc - 1; // std::vector optimizationResults( // numberOfOptimizationResults); @@ -39,16 +65,22 @@ int main(int argc, char *argv[]) // commandLineParameterIndex++) // optimizationResults[commandLineParameterIndex].load(argv[commandLineParameterIndex + 1]); - // for (const auto &dirEntry : std::filesystem::directory_iterator( - std::filesystem::path optimizationResultsPath0( - "/home/iason/Coding/build/ReducedModelOptimization/RelWithDebInfo/OptimizationResults/" - "ConvergedJobs"); - std::filesystem::path optimizationResultsPath1( - "/home/iason/Coding/Projects/Approximating shapes with flat " - "patterns/ReducedModelOptimization/Results/selectionOfPatterns_0.2To1.6/" - "selectionOfPatterns/1.2/ConvergedJobs"); + const std::filesystem::path optimizationResultsPath = argv[2]; + // std::filesystem::path optimizationResultsPath0( + // "/home/iason/Coding/Projects/Approximating shapes with flat " + // "patterns/ReducedModelOptimization/Results/selectionOfPatterns2"); + // std::filesystem::path optimizationResultsPath1( + // "/home/iason/Coding/Projects/Approximating shapes with flat " + // "patterns/ReducedModelOptimization/Results/selectionOfPatterns_0.2To1.6/" + // "selectionOfPatterns/1.2/ConvergedJobs"); + // std::filesystem::path optimizationResultsPath2( + // "/home/iason/Coding/Projects/Approximating shapes with flat " + // "patterns/ReducedModelOptimization/Results/selectionOfPatterns3"); + // std::filesystem::path optimizationResultsPath3( + // "/home/iason/Coding/Projects/Approximating shapes with flat " + // "patterns/ReducedModelOptimization/Results/selectionOfPatterns4"); std::vector optimizationResults - = ReducedPatternSimulator::loadOptimizationResults(optimizationResultsPath1); + = ReducedPatternSimulator::loadOptimizationResults(optimizationResultsPath); //Load reduced const std::filesystem::path patternFilePath( "/home/iason/Coding/Projects/Approximating shapes with flat " diff --git a/src/reducedpatternsimulator.cpp b/src/reducedpatternsimulator.cpp index fa2872c..9f5c8a5 100644 --- a/src/reducedpatternsimulator.cpp +++ b/src/reducedpatternsimulator.cpp @@ -62,11 +62,17 @@ std::pair ReducedPatternSimu // std::cout << "Running " << scenarioLabel << std::endl; pJob_tiledFullPattern->label = scenarioLabel; pJob_tiledReducedPattern->label = scenarioLabel; - const std::filesystem::path outputPath( - std::filesystem::path("/home/iason/Coding/build/PatternTillingReducedModel/Scenarios/") - .append(scenarioLabel)); + const std::filesystem::path surfaceOutputPath + = std::filesystem::path("/home/iason/Coding/build/PatternTillingReducedModel/Scenarios/") + .append(surfaceLabel); + //Tesselation + const std::filesystem::path tesselationFolderPath = std::filesystem::path(surfaceOutputPath) + .append("Tessellations"); + saveTesselation(tesselationFolderPath); + const std::filesystem::path scenarioOutputPath( + std::filesystem::path(surfaceOutputPath).append(scenarioLabel)); const std::string simJobsOutputFolderPath( - std::filesystem::path(outputPath).append("SimulationJobs").string()); + std::filesystem::path(scenarioOutputPath).append("SimulationJobs").string()); std::filesystem::create_directories(simJobsOutputFolderPath); // if (!std::filesystem::exists(simJobsOutputFolderPath)) { @@ -76,10 +82,21 @@ std::pair ReducedPatternSimu LinearSimulationModel linearSimulationModel; SimulationResults simulationResults_reducedPattern = linearSimulationModel.executeSimulation( pJob_tiledReducedPattern); + simulationResults_reducedPattern.setLabelPrefix("Reduced"); + const bool wasSuccessful = simulationResults_reducedPattern.saveDeformedModel( + scenarioOutputPath.string()); + SimulationResults simulationResults_fullPattern_linear = linearSimulationModel.executeSimulation( + pJob_tiledFullPattern); + simulationResults_fullPattern_linear.setLabelPrefix("FullLinear"); + simulationResults_fullPattern_linear.saveDeformedModel(scenarioOutputPath.string()); + if (showReducedPatternResultsBeforeRunningDRM) { simulationResults_reducedPattern.registerForDrawing(); + simulationResults_fullPattern_linear.registerForDrawing(); polyscope::show(); + // polyscope::requestRedraw(); simulationResults_reducedPattern.unregister(); + simulationResults_fullPattern_linear.unregister(); } // const auto reducedResultsFolderPath = std::filesystem::path(outputPath) // .append("ReducedResults") @@ -89,53 +106,73 @@ std::pair ReducedPatternSimu //Full const auto fullResultsFolderPath - = std::filesystem::path(outputPath).append("FullResults").append(fullPatternsLabel); - SimulationResults simulationResults_fullPattern; + = std::filesystem::path(scenarioOutputPath).append("FullResults").append(fullPatternsLabel); if (shouldRerunFullPatternSimulation && std::filesystem::exists(fullResultsFolderPath)) { std::filesystem::remove_all(fullResultsFolderPath); } const std::filesystem::path fullPatternJobFolderPath = std::filesystem::path(simJobsOutputFolderPath).append(fullPatternsLabel); + SimulationResults simulationResults_fullPattern_drm; if (std::filesystem::exists(fullResultsFolderPath) && !randomTesselationIsEnabled) { //Load full pattern results assert(std::filesystem::exists(fullPatternJobFolderPath)); - simulationResults_fullPattern.load(fullResultsFolderPath, fullPatternJobFolderPath); - simulationResults_fullPattern.converged = true; + simulationResults_fullPattern_drm.load(fullResultsFolderPath, fullPatternJobFolderPath); + simulationResults_fullPattern_drm.converged = true; } else { //Full DRMSimulationModel drmSimulationModel; DRMSimulationModel::Settings drmSimulationSettings; drmSimulationSettings.isDebugMode = true; - drmSimulationSettings.shouldDraw = true; - drmSimulationSettings.drawingStep = 100000; - drmSimulationSettings.beVerbose = false; - drmSimulationSettings.shouldCreatePlots = true; - drmSimulationSettings.Dtini = 0.1; - drmSimulationSettings.totalExternalForcesNormPercentageTermination = 0.001; + drmSimulationSettings.debugModeStep = 50000; + // drmSimulationSettings.shouldCreatePlots = true; + // drmSimulationSettings.drawingStep = 50000; + // drmSimulationSettings.shouldDraw = true; + // drmSimulationSettings.drawingStep = 100 * drmSimulationSettings.debugModeStep; + drmSimulationSettings.beVerbose = true; + // drmSimulationSettings.desiredGradualExternalLoadsSteps = 10; + // drmSimulationSettings.shouldCreatePlots = true; + drmSimulationSettings.useAverage = true; + // drmSimulationSettings.displacementCap = 0.1 * surfaceBaseTriangleHeight; + // drmSimulationSettings.xi = 0.97; + // drmSimulationSettings.Dtini = 0.06; + // drmSimulationSettings.gamma = 0.3; + drmSimulationSettings.totalExternalForcesNormPercentageTermination = 1e-1; // drmSimulationSettings.shouldUseTranslationalKineticEnergyThreshold = true; - // drmSimulationSettings.totalTranslationalKineticEnergyThreshold = 1e-10; + // drmSimulationSettings.totalTranslationalKineticEnergyThreshold = 1e-15; - // PolyscopeInterface::deinitPolyscope(); - simulationResults_fullPattern = drmSimulationModel.executeSimulation(pJob_tiledFullPattern, - drmSimulationSettings); - if (!simulationResults_fullPattern.converged) { - std::cerr << "Full pattern simulation failed." << std::endl; + // PolyscopeInterface::deinitPolyscope(); + const double forceScaleFactor = 0.5; + for (auto &externalForce : pJob_tiledFullPattern->nodalExternalForces) { + externalForce.second = externalForce.second * forceScaleFactor; } - - if (!randomTesselationIsEnabled && simulationResults_fullPattern.converged) { + SimulationResults simulationResults_fullPatternLinearModel + = linearSimulationModel.executeSimulation(pJob_tiledFullPattern); + // simulationResults_fullPatternLinearModel.save(fullResultsFolderPath); + for (auto &externalForce : pJob_tiledFullPattern->nodalExternalForces) { + externalForce.second = externalForce.second / forceScaleFactor; + } + simulationResults_fullPattern_drm + = drmSimulationModel.executeSimulation(pJob_tiledFullPattern, + drmSimulationSettings, + simulationResults_fullPatternLinearModel); + // simulationResults_fullPattern_drm + // = drmSimulationModel.executeSimulation(pJob_tiledFullPattern, drmSimulationSettings); + if (!simulationResults_fullPattern_drm.converged) { + std::cerr << "Full pattern simulation failed." << std::endl; + } else if (!randomTesselationIsEnabled) { std::filesystem::create_directories(fullResultsFolderPath); - simulationResults_fullPattern.save(fullResultsFolderPath); + simulationResults_fullPattern_drm.save(fullResultsFolderPath); pJob_tiledFullPattern->save(fullPatternJobFolderPath); } } - return std::make_pair(simulationResults_fullPattern, simulationResults_reducedPattern); + return std::make_pair(simulationResults_fullPattern_drm, simulationResults_reducedPattern); } void ReducedPatternSimulator::tileReducedPatterns( const std::vector &optimizationResults, - const std::vector &perSurfaceFacePatternIndices, + const std::vector &perSurfaceFacePatternIndices, std::shared_ptr &pSimulationMesh_tiledReduced, std::vector &tileIntoEdgeToTiledReducedVi) { @@ -189,10 +226,9 @@ void ReducedPatternSimulator::tileReducedPatterns( void ReducedPatternSimulator::shuffleReducedPatterns( const std::vector &optimizationResults, const std::vector &tileIntoEdgeToTiledFullPattern, - const std::vector &perSurfaceFacePatternIndices) + const std::vector &perSurfaceFacePatternIndices) { - std::vector randomShufflePerSurfaceFacePatternIndices - = perSurfaceFacePatternIndices; + std::vector randomShufflePerSurfaceFacePatternIndices = perSurfaceFacePatternIndices; std::random_shuffle(randomShufflePerSurfaceFacePatternIndices.begin(), randomShufflePerSurfaceFacePatternIndices.end()); std::vector tileIntoEdgesToTiledReducedVi; @@ -230,7 +266,9 @@ std::vector ReducedPatternSimulator::computeDistancesPerScenario( std::vector fullReducedDistancesPerScenario(scenarioLabels.size()); for (size_t scenarioIndex = 0; scenarioIndex < scenarioLabels.size(); scenarioIndex++) { const std::string &scenarioLabel = scenarioLabels[scenarioIndex]; - // std::cout << "Running:" << scenarioLabel << std::endl; + if (shouldRerunDRMSimulation) { + std::cout << "Running:" << scenarioLabel << std::endl; + } fullReducedDistancesPerScenario[scenarioIndex] = computeDistance(scenarioLabel, shouldRerunDRMSimulation, shouldDraw); @@ -240,10 +278,10 @@ std::vector ReducedPatternSimulator::computeDistancesPerScenario( return fullReducedDistancesPerScenario; } -std::vector ReducedPatternSimulator::computePerSurfaceFacePatternsIndices( +std::vector ReducedPatternSimulator::computePerSurfaceFacePatternsIndices( const std::vector &optimizationResults) const { - std::vector perSurfaceFacePatternIndices(pTileIntoSurface->FN()); + std::vector perSurfaceFacePatternIndices(pTileIntoSurface->FN()); if (randomTesselationIsEnabled) { for (size_t tileIntoFi = 0; tileIntoFi < pTileIntoSurface->FN(); tileIntoFi++) { const size_t randomPatternIndex = (rand() @@ -281,7 +319,7 @@ std::vector ReducedPatternSimulator::loadOp } void ReducedPatternSimulator::tileFullPatterns( std::vector &fullPatterns, - const std::vector &perSurfaceFacePatternIndices, + const std::vector &perSurfaceFacePatternIndices, std::shared_ptr &pTiledFullPattern_simulationMesh, std::vector &tileIntoEdgeToTiledFullVi) { @@ -296,7 +334,7 @@ void ReducedPatternSimulator::tileFullPatterns( perPatternIndexTiledFullPatternEdgeIndices); pTiledFullPattern->setLabel("Tiled_full_patterns"); //#ifdef POLYSCOPE_DEFINED - pTiledFullPattern->registerForDrawing(); + // pTiledFullPattern->registerForDrawing(); // polyscope::show(); // pTiledFullPattern->unregister(); //#endif @@ -330,7 +368,7 @@ void ReducedPatternSimulator::constructViMaps( void ReducedPatternSimulator::createShufflings( std::vector &optimizationResults) { - std::vector shuffledPerSurfaceFacePatternIndices = computePerSurfaceFacePatternsIndices( + std::vector shuffledPerSurfaceFacePatternIndices = computePerSurfaceFacePatternsIndices( optimizationResults); std::random_shuffle(shuffledPerSurfaceFacePatternIndices.begin(), shuffledPerSurfaceFacePatternIndices.end()); @@ -347,7 +385,7 @@ void ReducedPatternSimulator::runWeightEvaluation( && pTileIntoSurface->FN() == 22); std::filesystem::path bestPerformingFolder; double minDist = std::numeric_limits::max(); - std::vector> shufflings = csvFile::parse( + std::vector> shufflings = csvFile::parse( std::filesystem::path("/home/iason/Coding/build/PatternTillingReducedModel/RelWithDebInfo") .append("shufflings.csv")); const size_t numberOfShufflings = shufflings.size(); @@ -359,7 +397,7 @@ void ReducedPatternSimulator::runWeightEvaluation( = loadOptimizationResults(std::filesystem::path(p).append("ConvergedJobs")); double averageDistanceOverAllShufflings = 0; // computePerSurfaceFacePatternsIndices(optimizationResults); - for (std::vector shuffledPerSurfaceFacePatternIndices : shufflings) { + for (std::vector shuffledPerSurfaceFacePatternIndices : shufflings) { // for (const auto &el : shuffledPerSurfaceFacePatternIndices) { // std::cout << el << " "; // } @@ -391,7 +429,7 @@ void ReducedPatternSimulator::runShufflingEvaluation( { assert(pTileIntoSurface->VN() == 62 && pTileIntoSurface->EN() == 83 && pTileIntoSurface->FN() == 22); - std::vector perSurfaceFacePatternIndices = computePerSurfaceFacePatternsIndices( + std::vector perSurfaceFacePatternIndices = computePerSurfaceFacePatternsIndices( optimizationResults); std::vector nonShuffledDistances = computeDistancesPerScenario(scenariosTestSetLabels); const size_t numberOfShufflings = 500; @@ -403,6 +441,9 @@ void ReducedPatternSimulator::runShufflingEvaluation( tileIntoEiToTiledFullVi, perSurfaceFacePatternIndices); shuffledDistances[shufflingIndex] = computeDistancesPerScenario(scenariosTestSetLabels); + if (shufflingIndex % (numberOfShufflings / 10) == 0) { + std::cout << "Shuffling index:" << shufflingIndex << std::endl; + } // for (size_t scenarioIndex = 0; scenarioIndex < scenariosTestSetLabels.size(); // scenarioIndex++) { // const bool shuffledPerformsBetter = shuffledDistances[shufflingIndex][scenarioIndex] @@ -450,13 +491,18 @@ void ReducedPatternSimulator::runShufflingEvaluation( std::string simplifiedLabel(label.begin() + 6, label.end()); simplifiedLabel.erase(std::remove(simplifiedLabel.begin(), simplifiedLabel.end(), '_'), simplifiedLabel.end()); - // if (simplifiedLabel.size() > 12) { - // simplifiedLabel.insert(simplifiedLabel.begin() + 12, "\n"); - // } - // simplifiedLabel = "a\na"; - const size_t beginPos = simplifiedLabel.find("pullOppositeVerts"); - if (beginPos != simplifiedLabel.npos) { - simplifiedLabel.replace(beginPos, std::string("pullOppositeVerts").size(), "POV"); + const size_t beginPos_pov = simplifiedLabel.find("pullOppositeVerts"); + if (beginPos_pov != simplifiedLabel.npos) { + simplifiedLabel.replace(beginPos_pov, + std::string("pullOppositeVerts").size(), + "POV"); + } + + const size_t beginPos_random = simplifiedLabel.find("randomBending"); + if (beginPos_random != simplifiedLabel.npos) { + simplifiedLabel.replace(beginPos_random, + std::string("randomBending").size(), + "random"); } return simplifiedLabel; @@ -478,52 +524,131 @@ void ReducedPatternSimulator::runShufflingEvaluation( } std::pair -ReducedPatternSimulator::getPickedVertices(const std::pair &selection) const +ReducedPatternSimulator::getPickedInterfaceVertices( + const std::pair &selection) const { - std::shared_ptr &pTiledFullPattern_simulationMesh = pJob_tiledFullPattern->pMesh; - assert(pTiledFullPattern_simulationMesh != nullptr); - std::shared_ptr &pTiledReducedPattern_simulationMesh = pJob_tiledReducedPattern - ->pMesh; - assert(pTiledReducedPattern_simulationMesh != nullptr); - const int &vi = selection.second; + auto tiledFullPattern_polyscopeHandle = polyscope::getCurveNetwork( + pTiledFullPattern_simulationMesh->getLabel()); + auto tiledReducedPattern_polyscopeHandle = polyscope::getCurveNetwork( + pTiledReducedPattern_simulationMesh->getLabel()); const std::string &pickedStructureName = selection.first; + const bool pickedFull = pickedStructureName == tiledFullPattern_polyscopeHandle->name; + const bool pickedReduced = pickedStructureName == tiledReducedPattern_polyscopeHandle->name; + if (!(pickedFull || pickedReduced)) { + return std::make_pair(-1, -1); + } + + const bool vertexWasPicked = pickedFull + ? selection.second < tiledFullPattern_polyscopeHandle->nNodes() + : selection.second + < tiledReducedPattern_polyscopeHandle->nNodes(); + if (!vertexWasPicked) { + return std::make_pair(-1, -1); + } + const int &vi = selection.second; assert(!pickedStructureName.empty()); int fullVi = -1; int reducedVi = -1; - if (pickedStructureName == pTiledFullPattern_simulationMesh->getLabel()) { + if (pickedFull) { fullVi = vi; + if (!fullToReducedViMap.contains(fullVi)) { + return std::make_pair(-1, -1); + } reducedVi = fullToReducedViMap.at(vi); - } else if (pickedStructureName == pTiledReducedPattern_simulationMesh->getLabel()) { + } else if (pickedReduced) { reducedVi = vi; + if (!reducedToFullViMap.contains(reducedVi)) { + return std::make_pair(-1, -1); + } fullVi = reducedToFullViMap.at(vi); } return std::make_pair(fullVi, reducedVi); } -void ReducedPatternSimulator::reset() +void ReducedPatternSimulator::removeDrawnSimulationJobs() { - minInputForceMagnitude = std::numeric_limits::max(); - //Keep only initial patterns for (std::pair> polyscopeStructureCategory : polyscope::state::structures) { for (std::pair polyscopeStructure : polyscopeStructureCategory.second) { - if (polyscopeStructure.first != pTiledReducedPattern_simulationMesh->getLabel() - && polyscopeStructure.first != pTiledFullPattern_simulationMesh->getLabel()) { + if ((pTiledReducedPattern_simulationMesh + && polyscopeStructure.first != pTiledReducedPattern_simulationMesh->getLabel()) + && polyscopeStructure.first != pTiledFullPattern_simulationMesh->getLabel() + && polyscopeStructure.first != pTileIntoSurface->getLabel()) { polyscope::removeStructure(polyscopeStructure.second); } else { - dynamic_cast(polyscopeStructure.second) - ->removeAllQuantities(); + if (dynamic_cast(polyscopeStructure.second)) { + dynamic_cast(polyscopeStructure.second) + ->removeAllQuantities(); + } else if (dynamic_cast(polyscopeStructure.second)) + dynamic_cast(polyscopeStructure.second) + ->removeAllQuantities(); } } } + //Remove simulation job quantities from the initial meshes - pJob_tiledReducedPattern->unregister(pTiledReducedPattern_simulationMesh->getLabel()); - pJob_tiledReducedPattern->clear(); - pJob_tiledFullPattern->unregister(pTiledFullPattern_simulationMesh->getLabel()); - pJob_tiledFullPattern->clear(); + if (pTiledReducedPattern_simulationMesh && pJob_tiledReducedPattern) { + pJob_tiledReducedPattern->unregister(pTiledReducedPattern_simulationMesh->getLabel()); + pJob_tiledReducedPattern->clear(); + } + + if (pTiledFullPattern_simulationMesh && pJob_tiledFullPattern) { + pJob_tiledFullPattern->unregister(pTiledFullPattern_simulationMesh->getLabel()); + pJob_tiledFullPattern->clear(); + } + // if (pTiledReducedPattern_simulationMesh) { + // pTiledReducedPattern_simulationMesh->unregister(); + // } + // if (pTiledFullPattern_simulationMesh) { + // pTiledFullPattern_simulationMesh->unregister(); + // } +} + +void ReducedPatternSimulator::resetUserSelectedVertices() +{ + gui_fullPatternSelectedVertices.clear(); + gui_fullVerticesColors.clear(); + if (pTiledFullPattern_simulationMesh) { + gui_fullVerticesColors.resize(pTiledFullPattern_simulationMesh->VN()); + } + gui_reducedVerticesColors.clear(); + if (pTiledReducedPattern_simulationMesh) { + gui_reducedVerticesColors.resize(pTiledReducedPattern_simulationMesh->VN()); + } + polyscope::pick::resetSelection(); +} + +void ReducedPatternSimulator::resetUserSelectedFaces() +{ + gui_faceToPatternIndex.clear(); + gui_faceToPatternIndex.resize(pTileIntoSurface->FN(), -1); + gui_currentColorPatternIndexPair = {glm::vec3(1, 0, 0), 0}; + gui_colorsPerFace.clear(); + gui_colorsPerFace.resize(pTileIntoSurface->FN(), gui_currentColorPatternIndexPair.first); +} + +void ReducedPatternSimulator::removeTesselatedPatterns() +{ + if (pTiledReducedPattern_simulationMesh) { + pTiledReducedPattern_simulationMesh->unregister(); + pTiledReducedPattern_simulationMesh.reset(); + } + + if (pTiledFullPattern_simulationMesh) { + pTiledFullPattern_simulationMesh->unregister(); + pTiledFullPattern_simulationMesh.reset(); + } +} + +void ReducedPatternSimulator::reset() +{ + removeDrawnSimulationJobs(); + removeTesselatedPatterns(); + resetUserSelectedFaces(); + resetUserSelectedVertices(); polyscope::requestRedraw(); } @@ -609,20 +734,33 @@ void ReducedPatternSimulator::generateRandomSimulationScenario( while (pJob_tiledFullPattern->nodalExternalForces.size() / static_cast(tilledFullPatternInterfaceVi.size()) < percentageOfNodalForcesVertices) { - Vector6d externalForce({distFloat(rng) / 20, distFloat(rng) / 20, distFloat(rng), 0, 0, 0}); + const size_t fullTilledVi = tilledFullPatternInterfaceVi[distInt(rng)]; + if (usedVertices.contains(fullTilledVi)) { + continue; + } + // const double inPlaneForceMagnitude = 100 * std::abs(distFloat(rng)); + // const CoordType vertexPosition + // = pTiledFullPattern_simulationMesh->vert[fullTilledVi].cP().Normalize(); + + // Vector6d externalForce({inPlaneForceMagnitude * vertexPosition[0], + // inPlaneForceMagnitude * vertexPosition[1], + // distFloat(rng), + // 0, + // 0, + // 0}); + Vector6d externalForce; + if (distFloat(rng) > 0) { + externalForce = Vector6d({0, 0, distFloat(rng), 0, 0, 0}); + } else { + externalForce = Vector6d({distFloat(rng), distFloat(rng), 0, 0, 0, 0}); + } minInputForceMagnitude = std::min(minInputForceMagnitude, externalForce.norm()); - const size_t fullTilledVi = tilledFullPatternInterfaceVi[distInt(rng)]; - if (!usedVertices.contains(fullTilledVi)) { - pJob_tiledFullPattern->nodalExternalForces[fullTilledVi] = externalForce; - usedVertices.insert(fullTilledVi); - } + pJob_tiledFullPattern->nodalExternalForces[fullTilledVi] = externalForce; + usedVertices.insert(fullTilledVi); } - - //Apply the reduced job to the full pattern - pJob_tiledFullPattern->remap(fullToReducedViMap, *pJob_tiledReducedPattern); - pJob_tiledFullPattern->pMesh = pTiledFullPattern_simulationMesh; + pJob_tiledFullPattern->remap(fullToReducedViMap, *pJob_tiledReducedPattern); pJob_tiledReducedPattern->pMesh = pTiledReducedPattern_simulationMesh; } @@ -684,6 +822,23 @@ void ReducedPatternSimulator::reportDistances( csv_results << endrow; } +void ReducedPatternSimulator::reportDistances(const std::vector &scenarioLabels) +{ + for (const std::string &scenario : scenarioLabels) { + reset(); + gui_jobLabel = scenario; + // generateRandomSimulationScenario(gui_randomnessParams); + loadScenario(gui_jobLabel); + DRMFullSimulationResults drmFullTilledResults; + ReducedSimulationResults reducedTilledResults; + LinearFullSimulationResults linearFullTilledResults; + std::tie(drmFullTilledResults, reducedTilledResults, linearFullTilledResults) + = runAllSimulations(gui_jobLabel, gui_shouldRerunFullPatternSimulation, false); + reportDistances({drmFullTilledResults, reducedTilledResults, linearFullTilledResults}, + "distances.csv"); + } +} + std::tuple ReducedPatternSimulator::runAllSimulations(const std::string &jobLabel, const bool &shouldRerunDRMFullPatternSimulation, @@ -709,31 +864,98 @@ ReducedPatternSimulator::runAllSimulations(const std::string &jobLabel, return std::make_tuple(results.first, results.second, simulationResults_fullTilledLinearModel); } +void ReducedPatternSimulator::saveTesselation(const std::filesystem::path &saveTo) +{ + std::filesystem::create_directories(saveTo); + + nlohmann::json json; + const std::string jsonLabel_tesselation{"faceToPatternIndices"}; + json[jsonLabel_tesselation] = gui_faceToPatternIndex; + + std::filesystem::path jsonFilePath( + std::filesystem::path(saveTo).append(fullPatternsSurfacelabel + ".json")); + std::ofstream jsonFile(jsonFilePath.string()); + jsonFile << json; +} + +void ReducedPatternSimulator::computeSurfaceColorsFromPerFacePatterns( + const std::vector &faceToPatternIndex) +{ + std::set uniquePatternSet(faceToPatternIndex.begin(), faceToPatternIndex.end()); + const int numberOfDistinctPatterns = uniquePatternSet.size(); + std::vector surfaceColors(numberOfDistinctPatterns); + for (int colorIndex = 0; colorIndex < numberOfDistinctPatterns; colorIndex++) { + surfaceColors[colorIndex] = polyscope::getNextUniqueColor(); + } + + // gui_currentColorPatternIndexPair{glm::vec3(1, 0, 0), 0}; + for (int fi = 0; fi < pTileIntoSurface->FN(); fi++) { + const int patternIndex = gui_faceToPatternIndex[fi]; + // if (patternIndex != gui_currentColorPatternIndexPair.second) { + // gui_currentColorPatternIndexPair.first = surfaceColors[patternIndex]; + // gui_current + // } + gui_colorsPerFace[fi] = surfaceColors[patternIndex]; + } +} + +void ReducedPatternSimulator::loadTessellation(const std::filesystem::path &jsonFilePath) +{ + nlohmann::json json; + std::ifstream ifs(jsonFilePath); + ifs >> json; + const std::string jsonLabel_tesselation{"faceToPatternIndices"}; + gui_faceToPatternIndex = static_cast>(json.at(jsonLabel_tesselation)); + computeSurfaceColorsFromPerFacePatterns(gui_faceToPatternIndex); +} + +void ReducedPatternSimulator::updateTesselationColors() +{ + computeSurfaceColorsFromPerFacePatterns(gui_faceToPatternIndex); + auto tileIntoSurface_polyscopeHandle = polyscope::getSurfaceMesh(pTileIntoSurface->getLabel()); + tileIntoSurface_polyscopeHandle->addFaceColorQuantity("Selected faces", gui_colorsPerFace) + ->setEnabled(true); +} + void ReducedPatternSimulator::createGuiMenu() { // std::shared_ptr &pTiledFullPattern_simulationMesh = pJob_tiledFullPattern->pMesh; // assert(pTiledFullPattern_simulationMesh != nullptr); // std::shared_ptr &pTiledReducedPattern_simulationMesh = pJob_tiledReducedPattern // ->pMesh; - assert(pTiledReducedPattern_simulationMesh != nullptr); + // assert(pTiledReducedPattern_simulationMesh != nullptr); PolyscopeInterface::addUserCallback([&]() { // ImGuiIO &io = ImGui::GetIO(); if (ImGui::Button("Fix vertex")) { - const std::pair selection = PolyscopeInterface::getSelection(); - const std::string &pickedStructureName = selection.first; - if (pickedStructureName.empty()) { - return; + if (!gui_fullPatternSelectedVertices.empty()) { + for (const int fullVi : gui_fullPatternSelectedVertices) { + pJob_tiledFullPattern->constrainedVertices[fullVi] = {0, 1, 2, 3, 4, 5}; + pJob_tiledReducedPattern->constrainedVertices[fullToReducedViMap.at(fullVi)] + = {0, 1, 2, 3, 4, 5}; + } + resetUserSelectedVertices(); + } else { + const std::pair selection = PolyscopeInterface::getSelection(); + const std::string &pickedStructureName = selection.first; + if (pickedStructureName.empty()) { + return; + } + std::pair pickedVertices + = getPickedInterfaceVertices(selection); + if (pickedVertices.first == -1 && pickedVertices.second == -1) { + return; + } + pJob_tiledFullPattern->constrainedVertices[pickedVertices.first] = {0, 1, 2, 3, 4, 5}; + pJob_tiledReducedPattern->constrainedVertices[pickedVertices.second] + = {0, 1, 2, 3, 4, 5}; } - std::pair pickedVertices - = getPickedVertices(selection); - pJob_tiledFullPattern->constrainedVertices[pickedVertices.first] = {0, 1, 2, 3, 4, 5}; - pJob_tiledReducedPattern->constrainedVertices[pickedVertices.second] = {0, 1, 2, 3, 4, 5}; pJob_tiledFullPattern->registerForDrawing(pTiledFullPattern_simulationMesh->getLabel(), true); pJob_tiledReducedPattern ->registerForDrawing(pTiledReducedPattern_simulationMesh->getLabel(), true); polyscope::requestRedraw(); } + static int gui_dof = 0; ImGui::InputInt("DoF", &gui_dof); if (ImGui::Button("Constrain DoF of vertex")) { @@ -743,7 +965,10 @@ void ReducedPatternSimulator::createGuiMenu() return; } std::pair pickedVertices - = getPickedVertices(selection); + = getPickedInterfaceVertices(selection); + if (pickedVertices.first == -1 && pickedVertices.second == -1) { + return; + } pJob_tiledFullPattern->constrainedVertices[pickedVertices.first] = {gui_dof}; pJob_tiledReducedPattern->constrainedVertices[pickedVertices.second] = {gui_dof}; pJob_tiledFullPattern->registerForDrawing(pTiledFullPattern_simulationMesh->getLabel(), @@ -760,7 +985,10 @@ void ReducedPatternSimulator::createGuiMenu() return; } std::pair pickedVertices - = getPickedVertices(selection); + = getPickedInterfaceVertices(selection); + if (pickedVertices.first == -1 && pickedVertices.second == -1) { + return; + } pJob_tiledFullPattern->constrainedVertices[pickedVertices.first] = {0, 1, 2}; pJob_tiledReducedPattern->constrainedVertices[pickedVertices.second] = {0, 1, 2}; pJob_tiledFullPattern->registerForDrawing(pTiledFullPattern_simulationMesh->getLabel(), @@ -776,7 +1004,10 @@ void ReducedPatternSimulator::createGuiMenu() return; } std::pair pickedVertices - = getPickedVertices(selection); + = getPickedInterfaceVertices(selection); + if (pickedVertices.first == -1 && pickedVertices.second == -1) { + return; + } pJob_tiledFullPattern->constrainedVertices.erase(pickedVertices.first); pJob_tiledReducedPattern->constrainedVertices.erase(pickedVertices.second); pJob_tiledFullPattern->registerForDrawing(pTiledFullPattern_simulationMesh->getLabel(), @@ -786,6 +1017,35 @@ void ReducedPatternSimulator::createGuiMenu() polyscope::requestRedraw(); } + ImGui::InputFloat("Scale factor", &gui_scaleFactor); + if (ImGui::Button("Scale forces/moments")) { + if (!gui_fullPatternSelectedVertices.empty()) { + for (const int fullVi : gui_fullPatternSelectedVertices) { + pJob_tiledFullPattern->nodalExternalForces[fullVi] + = pJob_tiledFullPattern->nodalExternalForces[fullVi] * gui_scaleFactor; + const int reducedVi = fullToReducedViMap.at(fullVi); + pJob_tiledReducedPattern->nodalExternalForces[reducedVi] + = pJob_tiledReducedPattern->nodalExternalForces[reducedVi] + * gui_scaleFactor; + } + + resetUserSelectedVertices(); + } else { + for (auto &externalLoad : pJob_tiledFullPattern->nodalExternalForces) { + externalLoad.second = externalLoad.second * gui_scaleFactor; + } + for (auto &externalLoad : pJob_tiledReducedPattern->nodalExternalForces) { + externalLoad.second = externalLoad.second * gui_scaleFactor; + } + } + pJob_tiledFullPattern->registerForDrawing(pTiledFullPattern_simulationMesh->getLabel(), + true); + pJob_tiledReducedPattern + ->registerForDrawing(pTiledReducedPattern_simulationMesh->getLabel(), true); + + polyscope::requestRedraw(); + } + if (ImGui::Button("Set all forces/moments")) { const Vector6d desiredExternalLoad({gui_externalForce[0], gui_externalForce[1], @@ -809,26 +1069,38 @@ void ReducedPatternSimulator::createGuiMenu() polyscope::requestRedraw(); } if (ImGui::Button("Add force/moment")) { - const std::pair selection = PolyscopeInterface::getSelection(); - const std::string &pickedStructureName = selection.first; - if (pickedStructureName.empty()) { - return; - } - - std::pair pickedVertices - = getPickedVertices(selection); Vector6d externalForce({gui_externalForce[0], gui_externalForce[1], gui_externalForce[2], gui_externalMoment[0], gui_externalMoment[1], gui_externalMoment[2]}); - pJob_tiledFullPattern->nodalExternalForces[pickedVertices.first] = externalForce; - minInputForceMagnitude = std::min(minInputForceMagnitude, externalForce.norm()); + if (!gui_fullPatternSelectedVertices.empty()) { + for (const int fullVi : gui_fullPatternSelectedVertices) { + pJob_tiledFullPattern->nodalExternalForces[fullVi] = externalForce; + pJob_tiledReducedPattern->nodalExternalForces[fullToReducedViMap.at(fullVi)] + = externalForce; + } + + resetUserSelectedVertices(); + } else { + const std::pair selection = PolyscopeInterface::getSelection(); + const std::string &pickedStructureName = selection.first; + if (pickedStructureName.empty()) { + return; + } + + std::pair pickedVertices + = getPickedInterfaceVertices(selection); + if (pickedVertices.first == -1 && pickedVertices.second == -1) { + return; + } + pJob_tiledFullPattern->nodalExternalForces[pickedVertices.first] = externalForce; + pJob_tiledReducedPattern->nodalExternalForces[pickedVertices.second] = externalForce; + } + pJob_tiledFullPattern->registerForDrawing(pTiledFullPattern_simulationMesh->getLabel(), true); - pJob_tiledReducedPattern->nodalExternalForces[pickedVertices.second] = externalForce; - minInputForceMagnitude = std::min(minInputForceMagnitude, externalForce.norm()); pJob_tiledReducedPattern ->registerForDrawing(pTiledReducedPattern_simulationMesh->getLabel(), true); polyscope::requestRedraw(); @@ -843,7 +1115,10 @@ void ReducedPatternSimulator::createGuiMenu() return; } std::pair pickedVertices - = getPickedVertices(selection); + = getPickedInterfaceVertices(selection); + if (pickedVertices.first == -1 && pickedVertices.second == -1) { + return; + } pJob_tiledFullPattern->nodalExternalForces.erase(pickedVertices.first); pJob_tiledFullPattern->registerForDrawing(pTiledFullPattern_simulationMesh->getLabel(), true); @@ -853,17 +1128,49 @@ void ReducedPatternSimulator::createGuiMenu() polyscope::requestRedraw(); } - static std::string gui_jobLabel; ImGui::InputText("Job label", &gui_jobLabel); - if (ImGui::Button("Load job")) { - reset(); + // reset(); + removeDrawnSimulationJobs(); + resetUserSelectedFaces(); + resetUserSelectedVertices(); loadScenario(gui_jobLabel); polyscope::requestRedraw(); } - static bool gui_shouldRerunFullPatternSimulation = false; + ImGui::InputText("Tesselation label", &gui_tessellationLabel); + if (ImGui::Button("Load tesselation")) { + if (gui_tessellationLabel.empty()) { + return; + } + reset(); + + // const std::string fullPatternsOrderLabel = gui_tessellationLabel; + // const std::string tessellationFilename = computeFullPatternSetLabel(mOptimizationResults) + // + "_" + fullPatternsOrderLabel + "_" + // + pTileIntoSurface->getLabel(); + const std::string tessellationFilename = gui_tessellationLabel; + std::filesystem::path tessellationJsonPath( + std::filesystem::path( + "/home/iason/Coding/build/PatternTillingReducedModel/Scenarios") + .append(pTileIntoSurface->getLabel()) + .append("Tessellations") + .append(tessellationFilename + ".json")); + loadTessellation(tessellationJsonPath); + updateTesselationColors(); + resetTilledMeshes(); + + polyscope::requestRedraw(); + } + + if (ImGui::Button("Random tesselation")) { + reset(); + gui_faceToPatternIndex = computePerSurfaceFacePatternsIndices(mOptimizationResults); + updateTesselationColors(); + resetTilledMeshes(); + } + ImGui::Checkbox("Re-run full pattern simulation", &gui_shouldRerunFullPatternSimulation); if (ImGui::Button("Run Simulations")) { @@ -894,44 +1201,136 @@ void ReducedPatternSimulator::createGuiMenu() ImGui::InputFloat4("Randomness params", gui_randomnessParams.data()); if (ImGui::Button("Generate random scenario")) { gui_jobLabel = "22Hex_random"; + gui_shouldRerunFullPatternSimulation = true; reset(); generateRandomSimulationScenario(gui_randomnessParams); + pJob_tiledFullPattern->label = gui_jobLabel; pJob_tiledFullPattern->registerForDrawing(pTiledFullPattern_simulationMesh->getLabel(), true); pJob_tiledReducedPattern ->registerForDrawing(pTiledReducedPattern_simulationMesh->getLabel(), true); - polyscope::requestRedraw(); - } - if (ImGui::Button("Run random simulations")) { - const size_t numberOfRandomSimulations = 20; - gui_shouldRerunFullPatternSimulation = true; - for (size_t randomSimulationIndex = 0; - randomSimulationIndex < numberOfRandomSimulations; - randomSimulationIndex++) { - reset(); - gui_jobLabel = "22Hex_random" + std::to_string(randomSimulationIndex); - generateRandomSimulationScenario(gui_randomnessParams); - DRMFullSimulationResults drmFullTilledResults; - ReducedSimulationResults reducedTilledResults; - LinearFullSimulationResults linearFullTilledResults; - std::tie(drmFullTilledResults, reducedTilledResults, linearFullTilledResults) - = runAllSimulations(gui_jobLabel, gui_shouldRerunFullPatternSimulation, false); - reportDistances({drmFullTilledResults, - reducedTilledResults, - linearFullTilledResults}, - "distances.csv"); - // drmFullTilledResults.registerForDrawing(); - // reducedTilledResults.registerForDrawing(); - // linearFullTilledResults.registerForDrawing(); - // polyscope::requestRedraw(); - } + LinearSimulationModel linearSimulationModel; + SimulationResults simulationResults_fullTilledLinearModel + = linearSimulationModel.executeSimulation(pJob_tiledFullPattern); + simulationResults_fullTilledLinearModel.setLabelPrefix("LinearSimModel"); + simulationResults_fullTilledLinearModel.registerForDrawing(); + + polyscope::requestRedraw(); } if (ImGui::Button("Reset")) { reset(); } + + // Brush + ImGuiIO &io = ImGui::GetIO(); + if (io.KeyShift && polyscope::render::engine->isKeyPressed('b')) { + ImVec2 p = ImGui::GetMousePos(); + std::pair pickResult + = polyscope::pick::evaluatePickQuery(io.DisplayFramebufferScale.x * p.x, + io.DisplayFramebufferScale.y * p.y); + if (pickResult.first == nullptr) { + return; + } + polyscope::pick::setSelection(pickResult); + auto tileIntoSurface_polyscopeHandle = polyscope::getSurfaceMesh( + pTileIntoSurface->getLabel()); + const bool pickedFace = pickResult.first->name == tileIntoSurface_polyscopeHandle->name + && pickResult.second + >= tileIntoSurface_polyscopeHandle->facePickIndStart + && pickResult.second + < tileIntoSurface_polyscopeHandle->edgePickIndStart; + if (pickedFace) { + const size_t faceIndex = pickResult.second + - tileIntoSurface_polyscopeHandle->facePickIndStart; + // std::cout << "Picked face:" << faceIndex << std::endl; + gui_colorsPerFace[faceIndex] = gui_currentColorPatternIndexPair.first; + gui_faceToPatternIndex[faceIndex] = gui_currentColorPatternIndexPair.second; + + std::vector tileIntoEiToTiledFullPatternVi; + + fillFullPatterns(mOptimizationResults); + tileFullPatterns(fullPatterns, + gui_faceToPatternIndex, + pTiledFullPattern_simulationMesh, + tileIntoEiToTiledFullPatternVi); + + ///Create simulation jobs + // pJob_tiledFullPattern = std::make_shared(SimulationJob()); + // pJob_tiledFullPattern->label="TiledFull"; + // pJob_tiledReducedPattern = std::make_shared(SimulationJob()); + // pJob_tiledReducedPattern->setLabel("TiledReduced"); + // createSimulationJobs(externalForce, *pJob_tiledFullPattern, *pJob_tiledReducedPattern); + // pJob_tiledFullPattern->pMesh = pTiledFullPattern_simulationMesh; + if (pTiledFullPattern_simulationMesh + && polyscope::hasStructure(polyscope::CurveNetwork::structureTypeName, + pTiledFullPattern_simulationMesh->getLabel())) { + bool shouldEnableFullPattern = polyscope::getCurveNetwork( + pTiledFullPattern_simulationMesh->getLabel()) + ->isEnabled(); + pTiledFullPattern_simulationMesh + ->registerForDrawing(color_tesselatedFullPatterns) + ->setEnabled(shouldEnableFullPattern); + } else { + pTiledFullPattern_simulationMesh + ->registerForDrawing(color_tesselatedFullPatterns) + ->setEnabled(true); + } + // pJob_tiledReducedPattern->pMesh = pTiledReducedPattern_simulationMesh; + // pTiledReducedPattern_simulationMesh->registerForDrawing(); + } + tileIntoSurface_polyscopeHandle + ->addFaceColorQuantity("Selected faces", gui_colorsPerFace) + ->setEnabled(true); + polyscope::requestRedraw(); + } + if (io.KeyShift && polyscope::render::engine->isKeyPressed('n')) { + gui_currentColorPatternIndexPair.first = polyscope::getNextUniqueColor(); + gui_currentColorPatternIndexPair.second++; + } + if (io.KeyShift && polyscope::render::engine->isKeyPressed('t')) { + resetTilledMeshes(); + } + + if (io.KeyCtrl && io.KeyShift) { + if (polyscope::pick::haveSelection() + && (!pTiledFullPattern_simulationMesh || !pTiledReducedPattern_simulationMesh)) { + std::cerr << "Tiled patterns not registered. Tessellated patterns are required for " + "selecting a vertex." + << std::endl; + polyscope::pick::resetSelection(); + return; + } + // ImVec2 p = ImGui::GetMousePos(); + // std::pair pickResult + // = polyscope::pick::evaluatePickQuery(io.DisplayFramebufferScale.x * p.x, + // io.DisplayFramebufferScale.y * p.y); + // if (pickResult.first == nullptr) { + // return; + // } + const std::pair selection = PolyscopeInterface::getSelection(); + std::pair pickedVertices + = getPickedInterfaceVertices(selection); + if (pickedVertices.first == -1 && pickedVertices.second == -1) { + return; + } + gui_fullPatternSelectedVertices.push_back(pickedVertices.first); + gui_fullVerticesColors[pickedVertices.first] = glm::vec3(1, 0, 0); + auto tiledFullPattern_polyscopeHandle = polyscope::getCurveNetwork( + pTiledFullPattern_simulationMesh->getLabel()); + tiledFullPattern_polyscopeHandle + ->addNodeColorQuantity("Selected Vertices", gui_fullVerticesColors) + ->setEnabled(true); + gui_reducedVerticesColors[pickedVertices.second] = glm::vec3(1, 0, 0); + auto tiledReducedPattern_polyscopeHandle = polyscope::getCurveNetwork( + pTiledReducedPattern_simulationMesh->getLabel()); + tiledReducedPattern_polyscopeHandle + ->addNodeColorQuantity("Selected Vertices", gui_reducedVerticesColors) + ->setEnabled(true); + polyscope::requestRedraw(); + } }); } @@ -1038,13 +1437,15 @@ void ReducedPatternSimulator::createTiledSimulationMeshes( void ReducedPatternSimulator::loadScenario(const string &scenarioLabel) { std::filesystem::path simulationJobsInputFolderPath( - "/home/iason/Coding/build/PatternTillingReducedModel/SimulationJobs/"); - simulationJobsInputFolderPath.append(scenarioLabel); + std::filesystem::path("/home/iason/Coding/build/PatternTillingReducedModel/Scenarios") + .append(scenarioLabel) + .append("SimulationJobs")); if (!std::filesystem::exists(simulationJobsInputFolderPath) || !std::filesystem::is_directory(simulationJobsInputFolderPath)) { simulationJobsInputFolderPath = std::filesystem::path("/home/iason/Coding/build/PatternTillingReducedModel/Scenarios") + .append(surfaceLabel) .append(scenarioLabel) .append("SimulationJobs"); } @@ -1054,6 +1455,7 @@ void ReducedPatternSimulator::loadScenario(const string &scenarioLabel) << std::endl; return; } + // //Full // std::filesystem::path fullPatternSimulationJobFilePath; // for (auto &p : std::filesystem::recursive_directory_iterator( @@ -1098,30 +1500,68 @@ void ReducedPatternSimulator::loadScenario(const string &scenarioLabel) pJob_tiledFullPattern->registerForDrawing(pTiledFullPattern_simulationMesh->getLabel(), true); } -void ReducedPatternSimulator::computeLabels( - const std::vector &optimizationResults, - const std::vector &perSurfaceFacePatternIndex) +std::string ReducedPatternSimulator::computeFullPatternSetLabel( + const std::vector &optimizationResults) { - fullPatternsLabel.clear(); + std::string fullPatternSetLabel; for (OptimizationResultsIndex optResIndex = 0; optResIndex < optimizationResults.size(); optResIndex++) { - fullPatternsLabel += optimizationResults[optResIndex].baseTriangleFullPattern.getLabel() - + "_"; + fullPatternSetLabel += optimizationResults[optResIndex].baseTriangleFullPattern.getLabel() + + "_"; } - fullPatternsLabel += std::to_string(computeHashOrdered(perSurfaceFacePatternIndex)); + fullPatternSetLabel.pop_back(); + + return fullPatternSetLabel; +} + +void ReducedPatternSimulator::computeLabels( + const std::vector &optimizationResults, + const std::vector &perSurfaceFacePatternIndex) +{ + fullPatternsLabel.clear(); + const std::string fullPatternsSetLabel = computeFullPatternSetLabel(optimizationResults); + const std::string fullPatternsOrderLabel = std::to_string( + computeHashOrdered(perSurfaceFacePatternIndex)); + fullPatternsLabel = fullPatternsSetLabel + "_" + fullPatternsOrderLabel; // fullPatternsLabel += "_" + std::to_string(optimizationResults[0].settings.objectiveWeights.translational); - fullPatternsSurfacelabel = fullPatternsLabel + "_" + pTileIntoSurface->getLabel(); + surfaceLabel = pTileIntoSurface->getLabel(); + fullPatternsSurfacelabel = fullPatternsLabel + "_" + surfaceLabel; +} + +void ReducedPatternSimulator::resetTilledMeshes() +{ + std::vector tileIntoEiToTiledFullPatternVi; + createTiledSimulationMeshes( + pTileIntoSurface, + mOptimizationResults, + gui_faceToPatternIndex, + // std::vector(tileIntoSurface->FN(), 0), + tileIntoEiToTiledFullPatternVi); + + ///Create simulation jobs + pJob_tiledFullPattern = std::make_shared(SimulationJob()); + // pJob_tiledFullPattern->label="TiledFull"; + pJob_tiledReducedPattern = std::make_shared(SimulationJob()); + // pJob_tiledReducedPattern->setLabel("TiledReduced"); + // createSimulationJobs(externalForce, *pJob_tiledFullPattern, *pJob_tiledReducedPattern); + pJob_tiledFullPattern->pMesh = pTiledFullPattern_simulationMesh; + pTiledFullPattern_simulationMesh->registerForDrawing(color_tesselatedFullPatterns); + pJob_tiledReducedPattern->pMesh = pTiledReducedPattern_simulationMesh; + pTiledReducedPattern_simulationMesh->registerForDrawing(color_tesselatedReducedPatterns); + gui_fullVerticesColors.resize(pTiledFullPattern_simulationMesh->VN()); + gui_reducedVerticesColors.resize(pTiledReducedPattern_simulationMesh->VN()); } ReducedPatternSimulator::ReducedPatternSimulator( - const std::vector &optimizationResults) - : fullPatterns(optimizationResults.size()) + std::vector &optimizationResults) + : fullPatterns(optimizationResults.size()), mOptimizationResults(optimizationResults) {} void ReducedPatternSimulator::simulate( std::shared_ptr &tileIntoSurface, std::vector &optimizationResults, - PatternGeometry &reducedPattern) + PatternGeometry &reducedPattern, + const std::vector &inputPerSurfaceFacePatternIndices) { reducedPatternBaseTriangle = reducedPattern.computeBaseTriangle(); this->reducedPattern.copy(reducedPattern); @@ -1137,36 +1577,22 @@ void ReducedPatternSimulator::simulate( + optimizationResults[0].baseTriangle.cP(2)) / 2); preprocessSurface(optimizedBaseTriangleHeight, *pTileIntoSurface); - vcg::tri::io::ExporterOBJ::Save(*pTileIntoSurface, - "tileIntoSurface.obj", - vcg::tri::io::Mask::IOM_BITPOLYGONAL); + // vcg::tri::io::ExporterOBJ::Save(*pTileIntoSurface, + // "tileIntoSurface.obj", + // vcg::tri::io::Mask::IOM_BITPOLYGONAL); - std::vector perSurfaceFacePatternIndices = computePerSurfaceFacePatternsIndices( - optimizationResults); - std::vector tileIntoEiToTiledFullPatternVi; - createTiledSimulationMeshes(tileIntoSurface, - optimizationResults, - perSurfaceFacePatternIndices, - tileIntoEiToTiledFullPatternVi); + pTileIntoSurface->registerForDrawing()->setEdgeWidth(1); - ///Create simulation jobs - pJob_tiledFullPattern = std::make_shared(SimulationJob()); - // pJob_tiledFullPattern->label="TiledFull"; - pJob_tiledReducedPattern = std::make_shared(SimulationJob()); - // pJob_tiledReducedPattern->setLabel("TiledReduced"); - // createSimulationJobs(externalForce, *pJob_tiledFullPattern, *pJob_tiledReducedPattern); - pJob_tiledFullPattern->pMesh = pTiledFullPattern_simulationMesh; - pTiledFullPattern_simulationMesh->registerForDrawing(); - pJob_tiledReducedPattern->pMesh = pTiledReducedPattern_simulationMesh; - pTiledReducedPattern_simulationMesh->registerForDrawing(); - // pJob_tiledReducedPattern->registerForDrawing(pTiledReducedPattern_simulationMesh->getLabel()); - // pJob_tiledFullPattern->registerForDrawing(pTiledFullPattern_simulationMesh->getLabel()); + // TODO:REMOVE + reset(); + gui_faceToPatternIndex = computePerSurfaceFacePatternsIndices(mOptimizationResults); + resetTilledMeshes(); + removeDrawnSimulationJobs(); + loadScenario("ex1.1"); + + gui_colorsPerFace.resize(pTileIntoSurface->FN(), glm::vec3(0, 1, 0)); + gui_faceToPatternIndex.resize(pTileIntoSurface->FN(), -1); - // runShufflingEvaluation(optimizationResults, tileIntoEiToTiledFullPatternVi); - // runWeightEvaluation("/home/iason/Coding/Projects/Approximating shapes with flat " - // "patterns/ReducedModelOptimization/Results/selectionOfPatterns_0.2To1.6/" - // "selectionOfPatterns"); - // computeDistancesPerScenario(scenariosTestSetLabels, true); createGuiMenu(); polyscope::show(); } diff --git a/src/reducedpatternsimulator.hpp b/src/reducedpatternsimulator.hpp index a896f61..ad74b45 100644 --- a/src/reducedpatternsimulator.hpp +++ b/src/reducedpatternsimulator.hpp @@ -11,42 +11,65 @@ using LinearFullSimulationResults = SimulationResults; using ReducedSimulationResults = SimulationResults; using FullPatternVertexIndex = int; using ReducedPatternVertexIndex = int; +using OptimizationResultsIndex = int; class ReducedPatternSimulator { + std::vector &mOptimizationResults; std::shared_ptr pTiledFullPattern_simulationMesh; std::shared_ptr pTiledReducedPattern_simulationMesh; std::shared_ptr pJob_tiledReducedPattern; std::shared_ptr pJob_tiledFullPattern; + std::shared_ptr pTileIntoSurface; const Vector6d externalForce{0, 0, 0.1, 0, 0, 0}; double minInputForceMagnitude = std::numeric_limits::max(); + std::string gui_jobLabel; + std::string gui_tessellationLabel; + bool gui_shouldRerunFullPatternSimulation{false}; + float gui_scaleFactor{1}; + std::vector gui_fullVerticesColors; + std::vector gui_reducedVerticesColors; std::array gui_externalForce{0, 0, 0}; std::array gui_externalMoment{0, 0, 0}; - std::array gui_randomnessParams{0.02, 0.02, 0.3, 0.4}; + std::array gui_randomnessParams{0.02, 0.02, 0.1, 0.3}; + std::vector gui_faceToPatternIndex; + std::vector gui_fullPatternSelectedVertices; + std::pair gui_currentColorPatternIndexPair{glm::vec3(1, 0, 0), 0}; + std::vector gui_colorsPerFace; std::unordered_map fullToReducedViMap; //of only the common vertices std::unordered_map reducedToFullViMap; //of only the common vertices std::vector tilledFullPatternInterfaceVi; double surfaceBaseTriangleHeight{-1}; - std::string fullPatternsSurfacelabel; - std::string fullPatternsLabel; + std::array color_tesselatedFullPatterns{0.89, 0.61, 0.11}; + std::array color_tesselatedReducedPatterns{0.11, 0.89, 0.22}; + std::string fullPatternsSurfacelabel{"Empty label"}; + std::string fullPatternsLabel{"Empty label"}; + std::string surfaceLabel{"Empty label"}; + std::string fullPatternsOrderLabel{"Empty label"}; vcg::Triangle3 reducedPatternBaseTriangle; PatternGeometry reducedPattern; const bool randomTesselationIsEnabled{false}; - const std::vector scenariosTestSetLabels{// "22Hex_random0", - // "22Hex_random1", - // "22Hex_random2", - // "22Hex_random3", - // "22Hex_random4", - // "22Hex_random5", - // "22Hex_random6", - // "22Hex_random7", - // "22Hex_random8", - // "22Hex_random9", - // "22Hex_random10", - // "22Hex_random11", - // "22Hex_random12", - // "22Hex_random17", - // "22Hex_random14" + const std::vector scenariosTestSetLabels{"22Hex_randomBending0", + "22Hex_randomBending1", + "22Hex_randomBending2", + "22Hex_randomBending3", + "22Hex_randomBending4", + "22Hex_randomBending5", + "22Hex_randomBending6", + "22Hex_randomBending7", + "22Hex_randomBending8", + "22Hex_randomBending9", + "22Hex_randomBending10", + "22Hex_randomBending11", + "22Hex_randomBending12", + "22Hex_randomBending13", + "22Hex_randomBending14", + "22Hex_randomBending15", + "22Hex_randomBending16", + "22Hex_randomBending17", + "22Hex_randomBending18", + "22Hex_randomBending19", + "22Hex_randomBending20", "22Hex_bending_0.005N", "22Hex_bending_0.01N", "22Hex_bending_0.03N", @@ -66,11 +89,12 @@ class ReducedPatternSimulator std::unordered_map shuffleToNumOfOccur; public: - ReducedPatternSimulator( - const std::vector &optimizationResults); + ReducedPatternSimulator(std::vector &optimizationResults); void simulate(std::shared_ptr &tileIntoSurface, std::vector &optimizationResults, - PatternGeometry &reducedPattern); + PatternGeometry &reducedPattern, + const std::vector &perSurfaceFacePatternIndices + = std::vector()); /* * centers the surface * scales it such that its average base triangle size matches a desired one. This is done in order to match the base triangle on which the reduced pattern was optimized on @@ -88,13 +112,12 @@ public: const std::filesystem::path &optimizationResultsFolderPath); private: - std::shared_ptr pTileIntoSurface; std::vector fullPatterns; static void createSimulationJobs(const Vector6d &externalForce, SimulationJob &job_fullPattern, SimulationJob &job_reducedPattern); void createGuiMenu(); - std::pair getPickedVertices( + std::pair getPickedInterfaceVertices( const std::pair &selection) const; void reset(); void saveJobs(const filesystem::__cxx11::path &outputFolderPath); @@ -103,7 +126,6 @@ private: SimulationResults &reducedResults); void createTiledSimulationMeshes(std::vector &fullPatterns, std::vector &reducedPatterns); - using OptimizationResultsIndex = size_t; void createTiledSimulationMeshes( const std::shared_ptr &pTileIntoSurface, std::vector &optimizationResults, @@ -137,25 +159,25 @@ private: const bool &shouldDraw); void tileReducedPatterns( const std::vector &optimizationResults, - const std::vector &perSurfaceFacePatternIndices, + const std::vector &perSurfaceFacePatternIndices, std::shared_ptr &pSimulationMesh_tiledReduced, std::vector &tileIntoEdgeToTiledReduced); void shuffleReducedPatterns( const std::vector &optimizationResults, const std::vector &tileIntoEdgeToTiledFullPattern, - const std::vector &perSurfaceFacePatternIndices); + const std::vector &perSurfaceFacePatternIndices); void runWeightEvaluation(const std::filesystem::path &optimizationResultsFolderPath); void constructViMaps(const std::vector &tileIntoEdgeToTiledFullPattern, const std::vector &tileIntoEdgeToTiledReducedPattern); - std::vector computePerSurfaceFacePatternsIndices( + std::vector computePerSurfaceFacePatternsIndices( const std::vector &optimizationResults) const; void tileFullPatterns(std::vector &fullPatterns, - const std::vector &perSurfaceFacePatternIndices, + const std::vector &perSurfaceFacePatternIndices, std::shared_ptr &pTiledFullPattern_simulationMesh, std::vector &tileIntoEdgeToTiledFullVi); void fillFullPatterns(std::vector &optimizationResults); void computeLabels(const std::vector &optimizationResults, - const std::vector &perSurfaceFacePatternIndex); + const std::vector &perSurfaceFacePatternIndex); void createShufflings(std::vector &optimizationResults); void generateRandomSimulationScenario(const std::array &randomScenarioParameters); std::tuple @@ -166,6 +188,18 @@ private: ReducedSimulationResults, LinearFullSimulationResults> &simulationResults, const string &csvFilePath = {}); + void reportDistances(const std::vector &scenarioLabels); + void saveTesselation(const std::filesystem::path &saveTo); + void removeDrawnSimulationJobs(); + void loadTessellation(const std::filesystem::path &jsonFilePath); + void computeSurfaceColorsFromPerFacePatterns(const std::vector &faceToPatternIndex); + void resetTilledMeshes(); + std::string computeFullPatternSetLabel( + const std::vector &optimizationResults); + void resetUserSelectedVertices(); + void resetUserSelectedFaces(); + void removeTesselatedPatterns(); + void updateTesselationColors(); }; #endif // REDUCEDPATTERNSIMULATOR_HPP