Skip to content

Commit

Permalink
Merge pull request #832 from wildmeshing/mtao/multimesh_naming_to_mul…
Browse files Browse the repository at this point in the history
…timesh_component

Convert tool to convert wmtk mesh types
  • Loading branch information
mtao authored Nov 16, 2024
2 parents 4c6ee8e + b63a823 commit 6ca2e12
Show file tree
Hide file tree
Showing 50 changed files with 1,284 additions and 339 deletions.
1 change: 1 addition & 0 deletions applications/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ add_application(tetwild ON)
add_application(cdt_opt ON)
add_application(shortest_edge_collapse ON)
add_application(insertion ON)
add_application(convert ON)
add_application(longest_edge_split ON)


Expand Down
25 changes: 25 additions & 0 deletions applications/convert/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
include(wmtk_add_application)
include(wmtk_register_jse_json)
wmtk_add_application(convert_app
main.cpp
)

target_compile_features(convert_app PUBLIC cxx_std_20)
#register_jse_json(APPLICATION_NAME convert INPUT convert_spec.json )

# convert requires the output component and the convert component
target_link_libraries(convert_app PRIVATE
wmtk::input
wmtk::output
wmtk::multimesh
wmtk::application_utils
)

wmtk_register_integration_test(
EXEC_NAME convert_app
CONFIG_FILE ${CMAKE_CURRENT_SOURCE_DIR}/test_config.json
CONFIG_PATH ${CMAKE_CURRENT_SOURCE_DIR}/examples
GIT_REPOSITORY "https://github.com/wildmeshing/data.git"
GIT_TAG 363f8e860673a4e4f68df6465b99e86809c96283
#EXTRA_ARGUMENTS run
)
35 changes: 35 additions & 0 deletions applications/convert/examples/camel.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"input": {
"input": [
{
"file": "unit_test/meshes/camel.msh",
"name_spec": "position"
},
{
"file": "unit_test/meshes/cameluv.msh",
"name_spec": "uv"
}
],
"output": {
"position": {
"file": "camel.hdf5",
"type": ".hdf5"
}
},
"tree": {
"position": "uv"
}
},
"stats": {
"position": {
"edges": 5607,
"faces": 3576,
"vertices": 2032
},
"position.uv": {
"edges": 5607,
"faces": 3576,
"vertices": 2032
}
}
}
34 changes: 34 additions & 0 deletions applications/convert/examples/camel_split_uv.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"input": {
"input": {
"file": "multimesh/camel.hdf5",
"name_spec": {
"position": "uv"
}
},
"output": {
"position": {
"file": "camel_pos",
"position_attribute": "vertices",
"type": ".vtu"
},
"position.uv": {
"file": "camel_uv",
"position_attribute": "vertices",
"type": ".vtu"
}
}
},
"stats": {
"position": {
"edges": 5607,
"faces": 3576,
"vertices": 2032
},
"position.uv": {
"edges": 5607,
"faces": 3576,
"vertices": 2032
}
}
}
33 changes: 33 additions & 0 deletions applications/convert/examples/make_boundary.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"input": {
"input": [
{
"file": "blub_open.msh",
"name_spec": "position"
}
],
"output": {
"position": {
"file": "blub.hdf5",
"type": ".hdf5"
}
},
"tree": {
"position": {
"dimension": 1,
"type": "boundary"
}
}
},
"stats": {
"position": {
"edges": 17504,
"faces": 11648,
"vertices": 5857
},
"position.boundary_1": {
"edges": 64,
"vertices": 64
}
}
}
40 changes: 40 additions & 0 deletions applications/convert/examples/split_uv.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"input": {
"input": [
{
"file": "unit_test/meshes/camel.msh",
"name_spec": "position"
},
{
"file": "unit_test/meshes/cameluv.msh",
"name_spec": "uv"
}
],
"output": {
"position": {
"file": "ogre_pos.vtu",
"position_attribute": "vertices"
},
"position.uv": {
"file": "ogre_uv.vtu",
"position_attribute": "vertices"
}
},
"root": "/home/mtao/.local/cpm/wmtk_data/aa0abd4658bb064515ee7cc2a7be87aa",
"tree": {
"position": "uv"
}
},
"stats": {
"position": {
"edges": 5607,
"faces": 3576,
"vertices": 2032
},
"position.uv": {
"edges": 5607,
"faces": 3576,
"vertices": 2032
}
}
}
197 changes: 197 additions & 0 deletions applications/convert/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@

#include <jse/jse.h>
#include <CLI/App.hpp>
#include <CLI/CLI.hpp>
#include <filesystem>
#include <nlohmann/json.hpp>
#include <wmtk/applications/utils/element_count_report.hpp>

#include <wmtk/Mesh.hpp>
#include <wmtk/utils/Logger.hpp>

#include <wmtk/components/input/InputOptions.hpp>
#include <wmtk/components/input/input.hpp>

#include <wmtk/components/output/OutputOptions.hpp>
#include <wmtk/components/output/output.hpp>
#include <wmtk/components/utils/resolve_path.hpp>

#include "CLI/CLI.hpp"
#include "wmtk/components/multimesh/MeshCollection.hpp"
#include "wmtk/components/multimesh/from_boundary.hpp"
#include "wmtk/components/multimesh/from_facet_bijection.hpp"
#include "wmtk/components/utils/PathResolver.hpp"

using namespace wmtk::components;
using namespace wmtk::applications;
using namespace wmtk;
namespace fs = std::filesystem;

namespace {
std::shared_ptr<wmtk::Mesh> merge_meshes(
wmtk::components::multimesh::MeshCollection& mc,
const nlohmann::json& js)
{
for (const auto& [parent, child_datas] : js.items()) {
auto& parent_mesh = mc.get_mesh(parent);
auto& parent_named_mesh = mc.get_named_multimesh(parent);
if (child_datas.is_string()) {
const auto child_name = child_datas.get<std::string>();
auto& child_mesh = mc.get_mesh(child_name);
auto& child_named_mesh = mc.get_named_multimesh(child_name);
components::multimesh::from_facet_bijection(parent_mesh, child_mesh);
parent_named_mesh.append_child_mesh_names(parent_mesh, child_named_mesh);
return parent_mesh.shared_from_this();

} else if (child_datas.is_object()) {
const std::string type = child_datas["type"];

if (type == "facet_bijection") {
const std::string child_name = child_datas["name"];
auto& child_mesh = mc.get_mesh(child_name);
auto& child_named_mesh = mc.get_named_multimesh(child_name);
components::multimesh::from_facet_bijection(parent_mesh, child_mesh);
parent_named_mesh.append_child_mesh_names(parent_mesh, child_named_mesh);
return parent_mesh.shared_from_this();

} else if (type == "boundary") {
const int64_t dimension = child_datas["dimension"];
std::string boundary_attr_name = fmt::format("boundary_{}", dimension);
if (child_datas.contains("boundary_attribute_name")) {
boundary_attr_name = child_datas["boundary_attribute_name"];
}

std::string boundary_mesh_name = fmt::format("boundary_{}", dimension);
if (child_datas.contains("boundary_mesh_name")) {
boundary_mesh_name = child_datas["boundary_mesh_name"];
}
auto mptr = components::multimesh::from_boundary(
parent_mesh,
wmtk::get_primitive_type_from_id(dimension),
boundary_attr_name);

auto& child_named_mesh = mc.emplace_mesh(*mptr, boundary_mesh_name);
parent_named_mesh.append_child_mesh_names(parent_mesh, child_named_mesh);

return parent_mesh.shared_from_this();
}
}
}
return nullptr;
}
} // namespace

int run(const fs::path& config_path /*, const std::optional<fs::path>& name_spec_file*/)
{
nlohmann::json j;
{
std::ifstream ifs(config_path);
j = nlohmann::json::parse(ifs);
// if (name_spec_file.has_value()) {
// j["name"] = nlohmann::json::parse(std::ifstream(name_spec_file.value()));
// }
}

spdlog::warn("{}", j.dump(2));

wmtk::components::multimesh::MeshCollection meshes;
components::utils::PathResolver path_resolver;

if (j.contains("root")) {
path_resolver = j["root"];
}

std::shared_ptr<wmtk::Mesh> output_mesh;
if (j["input"].is_array()) {
for (const auto& in_opts_js : j["input"]) {
wmtk::components::input::InputOptions opts = in_opts_js;
meshes.add_mesh(wmtk::components::input::input(opts, path_resolver));
}
} else {
wmtk::components::input::InputOptions opts = j["input"];
output_mesh = meshes.add_mesh(wmtk::components::input::input(opts, path_resolver))
.root()
.shared_from_this();
}

if (j.contains("tree")) {
output_mesh = merge_meshes(meshes, j["tree"]);
}

if (!j.contains("output")) {
wmtk::logger().info("convert: No output path provided");
} else if (j["output"].is_object()) {
for (const auto& [mesh_path, out_opts_js] : j["output"].items()) {
auto opts = out_opts_js.get<wmtk::components::output::OutputOptions>();

wmtk::components::output::output(meshes.get_mesh(mesh_path), opts);
}
} else {
auto opts = j["output"].get<wmtk::components::output::OutputOptions>();
wmtk::components::output::output(*output_mesh, opts);
}


if (j.contains("report")) {
const std::string report = j["report"];
meshes.make_canonical();
if (!report.empty()) {
nlohmann::json out_json;
auto& stats = out_json["stats"];
for (const auto& [name, mesh] : meshes.all_meshes()) {
stats[name] = wmtk::applications::utils::element_count_report_named(mesh);
}
j.erase("report");
out_json["input"] = j;


std::ofstream ofs(report);
ofs << out_json;
}
}
return 0;
}


int main(int argc, char* argv[])
{
CLI::App app{argv[0]};

app.ignore_case();

fs::path json_input_file;
std::optional<fs::path> name_spec_file;

CLI::App* run_cmd; // = app.add_subcommand("run", "Run application");
run_cmd = &app;
run_cmd->add_option("-j, --json", json_input_file, "json specification file")
->required(true)
->check(CLI::ExistingFile);

// run_cmd->add_option("-n, --name_spec", name_spec_file, "json specification file")
// ->check(CLI::ExistingFile);

CLI11_PARSE(app, argc, argv);

// someday may add other suboptions
assert(run_cmd->parsed());

// if (!json_input_file.has_value() && !fill_config_path.has_value()) {
// wmtk::logger().error("An input json file with [-j] is required unless blank config "
// "generation is being used with [--fill-config]");
// return 1;
// }

int exit_mode = -1;

// run_cmd->callback([&]() {
// spdlog::warn("YOW!");
// assert(json_input_file.has_value());
// exit_mode = run(json_input_file.value());
// });
exit_mode = run(json_input_file /*, name_spec_file*/);


assert(exit_mode != -1); // "Some subcommand should have updated the exit mode"
return exit_mode;
}
11 changes: 11 additions & 0 deletions applications/convert/test_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"tests": [
"camel.json",
"camel_split_uv.json",
"make_boundary.json",
"split_uv.json"
],
"input_tag": "input",
"oracle_tag": "report",
"input_directory_tag": "root"
}
Loading

0 comments on commit 6ca2e12

Please sign in to comment.