Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Isotropic Remeshing Part 2 (Works without MM) #812

Draft
wants to merge 70 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
66760d0
isotropic remeshing updates for future component updates
mtao Oct 6, 2024
1fdc217
Merge remote-tracking branch 'base/main' into mtao/isotropic_remeshing_2
mtao Oct 7, 2024
def8afc
enabling isotropic remeshing by default
mtao Oct 7, 2024
9166970
Updating input options to allow for custom working directories
mtao Oct 8, 2024
dcd7a75
adding more verbose output to integration test script
mtao Oct 8, 2024
6649181
removing spearation between uv and 3d isotropic remeshing
mtao Oct 8, 2024
e1d9539
updating procedural for updated output spec and removing integration …
mtao Oct 8, 2024
b214c08
robustness in input, adding tet example
mtao Oct 8, 2024
0b81f7e
blindly enabling isotropic remeshing in 3d
mtao Oct 8, 2024
91b69cb
removing input statement
mtao Oct 8, 2024
d780482
added smaller example to debug
danielepanozzo Oct 9, 2024
1dc359a
Merge branch 'mtao/isotropic_remeshing_2' of github.com:wildmeshing/w…
danielepanozzo Oct 9, 2024
da75dd2
valence improvement checks for boundary now, isotropic doesnt always …
mtao Oct 9, 2024
d32544b
updating trimesh names
mtao Oct 9, 2024
a47fee4
starting to check for tri vs tet swaps
mtao Oct 9, 2024
d0c7117
adding EdgeSwap basic class to represent splitt collapse pairs
mtao Oct 10, 2024
ef62e83
making things compile
mtao Oct 10, 2024
cb8f2dd
adding const getters and removing superfluous inline in edgeswap
mtao Oct 10, 2024
488777e
adding stuff
mtao Oct 12, 2024
adda62b
builds again now
mtao Oct 13, 2024
b312e6d
temporarily moving periodic opt into isotropic to merge together
mtao Oct 17, 2024
283b35a
cleaning up procedural and isotropic argument parsing to lie in imlem…
mtao Oct 18, 2024
553cac3
fixing procedural options setting
mtao Oct 19, 2024
f7e24f3
updates
mtao Oct 21, 2024
e45cb59
Merge remote-tracking branch 'upstream/main' into mtao/isotropic_reme…
mtao Oct 24, 2024
03d741a
fixing types of meshes in wildmeshing
mtao Oct 24, 2024
d2c8bd9
fixing noexcept compilation errors on gcc13
mtao Oct 24, 2024
4c577c6
cleaning up use of auto_size variable
mtao Oct 24, 2024
cbc79c3
Merge remote-tracking branch 'upstream/main' into mtao/isotropic_reme…
mtao Oct 26, 2024
719c123
fixing procedural main
mtao Oct 26, 2024
fe4e076
updating procedural run
mtao Oct 26, 2024
12115f2
Merge remote-tracking branch 'upstream/main' into mtao/isotropic_reme…
mtao Oct 27, 2024
6d5bfec
Merge remote-tracking branch 'upstream/main' into mtao/isotropic_reme…
mtao Nov 2, 2024
c72e19c
minor refactor in integration test runTest func
mtao Nov 2, 2024
a7a303b
trying to debug examples
mtao Nov 2, 2024
98b1b4e
reversing order of trimesh is_ccw autogen funcs to silence a warning
mtao Nov 2, 2024
9f94ea7
updates to isotropic remeshing
mtao Nov 2, 2024
21b7b67
still chasing why collapse is bad
mtao Nov 2, 2024
bb9282e
adding raw examples of isotropci remeshing despite not working yet
mtao Nov 4, 2024
76d2c17
Merge remote-tracking branch 'upstream/main' into mtao/isotropic_reme…
mtao Nov 5, 2024
c35b502
Merge remote-tracking branch 'upstream/main' into mtao/isotropic_reme…
mtao Nov 7, 2024
6cbc3d0
Merge remote-tracking branch 'upstream/main' into mtao/isotropic_reme…
mtao Nov 15, 2024
4ffdf75
Merge remote-tracking branch 'upstream/main' into mtao/isotropic_reme…
mtao Nov 16, 2024
09a7027
fixing input
mtao Nov 16, 2024
3e60ec6
formatting procedural examples
mtao Nov 16, 2024
49ca650
temporarily clearing test on cli11 callbacks in procedural
mtao Nov 16, 2024
fa4fe9d
fixing test ocnfig path in examples
mtao Nov 17, 2024
ef996c3
re-enabling collapse
mtao Nov 17, 2024
a4fd80e
adding element count report for isotropic remeshing and adding 100071…
mtao Nov 17, 2024
ea5dc3e
adding verbose flag for integration test script
mtao Nov 17, 2024
31759fb
clearing print statements on integration failure in verbose mode
mtao Nov 17, 2024
e673401
updates
mtao Nov 19, 2024
1f453ab
Moving utils to new folder
mtao Nov 19, 2024
5f65e69
update
mtao Nov 19, 2024
6be156c
Merge remote-tracking branch 'upstream/main' into mtao/isotropic_reme…
mtao Nov 21, 2024
c116daa
updates to tetmesh swap
mtao Nov 22, 2024
8f989b0
adding minor options to camel isotropic example
mtao Nov 22, 2024
b80f6c6
Merge branch 'mtao/isotropic_remeshing_2' of github.com:wildmeshing/w…
mtao Nov 22, 2024
fb3403a
Merge remote-tracking branch 'upstream/main' into mtao/isotropic_reme…
mtao Nov 22, 2024
aa7980c
builds now
mtao Nov 22, 2024
697e475
Merge branch 'mtao/isotropic_remeshing_2' of github.com:wildmeshing/w…
mtao Nov 22, 2024
1e1a6b8
Merge branch 'mtao/attribute_fetcher' into mtao/isotropic_remeshing_2
mtao Nov 22, 2024
726031a
Merge remote-tracking branch 'upstream/mtao/isotropic_remeshing_2' in…
mtao Nov 22, 2024
1ed2a34
update
mtao Nov 23, 2024
0fbdc06
Merge remote-tracking branch 'upstream/main' into mtao/isotropic_reme…
mtao Nov 25, 2024
0644b92
compiles agagian
mtao Nov 25, 2024
8a3d88e
adding get_integration_test stuff
mtao Nov 25, 2024
323df07
adding resolver path adding
mtao Nov 26, 2024
858bb3a
updating input and output to use path instead of file
mtao Nov 26, 2024
4c1b344
moving home, named multimesh default injection broken
mtao Nov 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion applications/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ add_application(delaunay ON)
add_application(marching ON)
add_application(procedural ON)
add_application(multimesh OFF)
add_application(isotropic_remeshing OFF)
add_application(isotropic_remeshing ON)
add_application(tetwild_simplification ON)
add_application(triwild ON)
add_application(tetwild ON)
Expand Down
103 changes: 82 additions & 21 deletions applications/convert/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <filesystem>
#include <nlohmann/json.hpp>
#include <wmtk/applications/utils/element_count_report.hpp>
#include <wmtk/applications/utils/get_integration_test_data_root.hpp>

#include <wmtk/Mesh.hpp>
#include <wmtk/utils/Logger.hpp>
Expand Down Expand Up @@ -81,25 +82,27 @@ std::shared_ptr<wmtk::Mesh> merge_meshes(
}
} // namespace

int run(const fs::path& config_path /*, const std::optional<fs::path>& name_spec_file*/)
int run_js(
const std::string_view& app_name,
const nlohmann::json& j,
const std::optional<fs::path>& name_spec_file,
const std::optional<fs::path>& integration_test_config_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));

// if (name_spec_file.has_value()) {
// j["name"] = nlohmann::json::parse(std::ifstream(name_spec_file.value()));
// }
wmtk::components::multimesh::MeshCollection meshes;
components::utils::PathResolver path_resolver;

if (j.contains("root")) {
path_resolver = j["root"];
}
if (integration_test_config_file.has_value()) {
auto path = wmtk::applications::utils::get_integration_test_data_root(
integration_test_config_file.value(),
app_name);
path_resolver.add_path(path);
}

std::shared_ptr<wmtk::Mesh> output_mesh;
if (j["input"].is_array()) {
Expand Down Expand Up @@ -133,16 +136,15 @@ int run(const fs::path& config_path /*, const std::optional<fs::path>& name_spec


if (j.contains("report")) {
nlohmann::json jnew = j;
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;
stats = wmtk::applications::utils::element_count_report_named(meshes);
jnew.erase("report");
out_json["input"] = jnew;


std::ofstream ofs(report);
Expand All @@ -152,6 +154,18 @@ int run(const fs::path& config_path /*, const std::optional<fs::path>& name_spec
return 0;
}

int run(
const std::string_view& app_name,
const fs::path& config_path,
const std::optional<fs::path>& name_spec_file,
const std::optional<fs::path>& integration_test_config_file)
{
nlohmann::json j;
std::ifstream ifs(config_path);
j = nlohmann::json::parse(ifs);

return run_js(app_name, j, name_spec_file, integration_test_config_file);
}

int main(int argc, char* argv[])
{
Expand All @@ -160,21 +174,50 @@ int main(int argc, char* argv[])
app.ignore_case();

fs::path json_input_file;
std::optional<fs::path> json_integration_config_file;
std::optional<std::string> json_integration_app_name;
std::optional<fs::path> name_spec_file;

CLI::App* run_cmd; // = app.add_subcommand("run", "Run application");
run_cmd = &app;
auto add_it_path = [&](CLI::App& a) {
a.add_option(
"-c, --integration-test-config",
json_integration_config_file,
"Test config file for integration test")
->check(CLI::ExistingFile);
a.add_option(
"-a, --integration-test-app",
json_integration_config_file,
"Test config file for integration test")
->check(CLI::ExistingFile);
};

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

add_it_path(*run_cmd);


fs::path input;
fs::path output;
std::string type;
CLI::App* type_cmd = app.add_subcommand("type", "Convert mesh to another type");
type_cmd->add_option("-i, --input", input, "input file")
->required(true)
->check(CLI::ExistingFile);

type_cmd->add_option("-o, --output", output, "output file");
type_cmd->add_option("-t, --type", type, "output file type");
add_it_path(*type_cmd);


// 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 "
Expand All @@ -189,7 +232,25 @@ int main(int argc, char* argv[])
// assert(json_input_file.has_value());
// exit_mode = run(json_input_file.value());
// });
exit_mode = run(json_input_file /*, name_spec_file*/);
if (run_cmd->parsed()) {
exit_mode = run(argv[0], json_input_file, name_spec_file, json_integration_config_file);
} else {
wmtk::components::input::InputOptions in;
in.path = input;
wmtk::components::output::OutputOptions out;
out.path = output;
out.position_attribute = "vertices";
if (!type.empty() && type[0] != '.') {
type = '.' + type;
}
out.type = type;

nlohmann::json js;
js["input"] = in;
js["output"][""] = out;

exit_mode = run_js(argv[0], js, name_spec_file, json_integration_config_file);
}


assert(exit_mode != -1); // "Some subcommand should have updated the exit mode"
Expand Down
44 changes: 25 additions & 19 deletions applications/integration_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ class IntegrationTest(unittest.TestCase):
BINARY_FOLDER = fix_path(os.environ['WMTK_BINARY_FOLDER']) if "WMTK_BINARY_FOLDER" in os.environ else None
CONFIG_FILE = fix_path(os.environ['WMTK_CONFIG_FILE']) if "WMTK_CONFIG_FILE" in os.environ else None

def __init__(self, name, test_config, configs_to_run = None, run_all = False):
# verbose = print stdout / stderr to the screen
def __init__(self, name, test_config, configs_to_run = None, run_all = False, verbose=False):
super().__init__()
self.working_dir_fp = tempfile.TemporaryDirectory()
self.working_dir = self.working_dir_fp.name
self.verbose= verbose

self.name = name
self.test_config = test_config
Expand Down Expand Up @@ -69,12 +71,15 @@ def tearDown(self):
def execute_json(self, json_file_path):

cmd = [self.executable] +self.extra_flags + [ "-j", json_file_path]
res = subprocess.run(cmd, cwd=self.working_dir, capture_output=True)
# capture input if we're not going to already print stuff
res = subprocess.run(cmd, cwd=self.working_dir, capture_output=not self.verbose)

if res.returncode != 0:
print(f"Error running [{' '.join(cmd)}]", flush=True)
print(res.stderr.decode('utf-8'), flush=True)
print(res.stdout.decode('utf-8'), flush=True)
print(f"Error running [{' '.join(cmd)}] from working directory [{self.working_dir}]")
# in verbose mode the stderr/stdout buffers were already flushed
if not self.verbose:
print(res.stderr.decode('utf-8'), flush=True)
print(res.stdout.decode('utf-8'), flush=True)
return res

def get_root_path(self, input_js):
Expand Down Expand Up @@ -171,21 +176,20 @@ def run_one(self, test_file):

self.assertTrue(True)

def runTestFile(self, test_file_name):
with self.subTest(msg=f"{self.name}-{test_file_name}"):
print("Running test", test_file_name, flush=True)
test_file = os.path.join(self.config_folder, test_file_name)
print(f"Test file: {test_file}", flush=True)
self.run_one(test_file)


def runTest(self):
for test_file_name in self.config["tests"]:
with self.subTest(msg=f"{self.name}-{test_file_name}"):
print("Running test", test_file_name, flush=True)
test_file = os.path.join(self.config_folder, test_file_name)
print(f"Test file: {test_file}", flush=True)
self.run_one(test_file)
self.runTestFile(test_file_name)
if self.run_all and "release_only_tests" in self.config:
for test_file_name in self.config["release_only_tests"]:
with self.subTest(msg=f"{self.name}-{test_file_name}"):
print("Running slow test", test_file_name, flush=True)
test_file = os.path.join(self.config_folder, test_file_name)
print(f"Test file: {test_file}", flush=True)
self.run_one(test_file)
self.runTestFile(test_file_name)


def load_config_json(config_file):
Expand All @@ -196,7 +200,7 @@ def load_config_json(config_file):
del config["skip"]
return config

def make_suite(config_file, single_application = None, single_config = None, run_all = False):
def make_suite(config_file, single_application = None, single_config = None, run_all = False, verbose=False):
config = load_config_json(config_file)

suite = unittest.TestSuite()
Expand All @@ -206,7 +210,7 @@ def make_suite(config_file, single_application = None, single_config = None, run
continue
if single_application is None or key == single_application:
# expects a list of configs to run
suite.addTest(IntegrationTest(key,value, None if single_config is None else [single_config], run_all))
suite.addTest(IntegrationTest(key,value, None if single_config is None else [single_config], run_all, verbose=verbose))
return suite


Expand All @@ -222,13 +226,15 @@ def make_suite(config_file, single_application = None, single_config = None, run
parser.add_argument('-t', '--test-application', help="Runs tests for a single application")
parser.add_argument('-s', '--test-script', help="Runs a particular test script")
parser.add_argument('-a', '--all-tests', help="Runs all tests, including slow ones", action='store_true')
parser.add_argument("-v", '--verbose', help="print execution data verbosely", action='store_true')

subparsers = parser.add_subparsers(help="subcommand help", dest="subcommand")
create_parser = subparsers.add_parser(name="create",help="create integration test json")

create_parser.add_argument("-b", '--binary', help="Name of the binary being run")
create_parser.add_argument("-i", '--input', help="input config")
create_parser.add_argument("-o", '--output', help="output config filename, placed in config folder")
create_parser.add_argument("-v", '--verbose', help="print execution data verbosely", action='store_true')

args = parser.parse_args()

Expand Down Expand Up @@ -260,7 +266,7 @@ def make_suite(config_file, single_application = None, single_config = None, run
# no subcommand chosen so we just run
if args.subcommand is None:
# test_application and test_script are None if not set
suite = make_suite(config_file, args.test_application, args.test_script, args.all_tests)
suite = make_suite(config_file, args.test_application, args.test_script, args.all_tests, verbose=args.verbose)

runner = unittest.TextTestRunner()
result = runner.run(suite)
Expand All @@ -277,7 +283,7 @@ def make_suite(config_file, single_application = None, single_config = None, run
config = load_config_json(config_file)
binary = args.binary
my_config = config[binary]
test = IntegrationTest(binary,my_config)
test = IntegrationTest(binary,my_config, verbose=args.verbose)
test.create_reporter(args.input,args.output)
pass

Expand Down
41 changes: 14 additions & 27 deletions applications/isotropic_remeshing/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,48 +10,35 @@ set(SHARED_STUFF
)


wmtk_add_application(isotropic_remeshing_3d_app
main_3d.cpp
wmtk_add_application(isotropic_remeshing_app
main.cpp
#spec.hpp
${SHARED_STUFF}
)

wmtk_add_application(isotropic_remeshing_uv_app
main_uv.cpp
#spec.hpp
${SHARED_STUFF}
)


# isotropic_remeshing requires the input component and the procedural component
target_link_libraries(isotropic_remeshing_3d_app PRIVATE
target_link_libraries(isotropic_remeshing_app PRIVATE
wmtk::input
wmtk::isotropic_remeshing
wmtk::multimesh
wmtk::output
wmtk::application_utils
)

target_link_libraries(isotropic_remeshing_uv_app PRIVATE
wmtk::input
wmtk::isotropic_remeshing
wmtk::output
wmtk::multimesh
wmtk::application_utils
)

wmtk_register_integration_test(
EXEC_NAME isotropic_remeshing_3d_app
CONFIG_FILE ${CMAKE_CURRENT_SOURCE_DIR}/test_config_3d.json
GIT_REPOSITORY "https://github.com/wildmeshing/data.git"
GIT_TAG 152a561697a6e923451ca8535309cbe1e116a9fa
CONFIG_PATH ${CMAKE_CURRENT_SOURCE_DIR}
)

wmtk_register_integration_test(
EXEC_NAME isotropic_remeshing_uv_app
CONFIG_FILE ${CMAKE_CURRENT_SOURCE_DIR}/test_config_uv.json
EXEC_NAME isotropic_remeshing_app
CONFIG_FILE ${CMAKE_CURRENT_SOURCE_DIR}/test_config.json
GIT_REPOSITORY "https://github.com/wildmeshing/data.git"
GIT_TAG 152a561697a6e923451ca8535309cbe1e116a9fa
CONFIG_PATH ${CMAKE_CURRENT_SOURCE_DIR}
CONFIG_PATH ${CMAKE_CURRENT_SOURCE_DIR}/examples
)
#
#wmtk_register_integration_test(
# EXEC_NAME isotropic_remeshing_uv_app
# CONFIG_FILE ${CMAKE_CURRENT_SOURCE_DIR}/test_config_uv.json
# GIT_REPOSITORY "https://github.com/wildmeshing/data.git"
# GIT_TAG 152a561697a6e923451ca8535309cbe1e116a9fa
# CONFIG_PATH ${CMAKE_CURRENT_SOURCE_DIR}
#)
30 changes: 30 additions & 0 deletions applications/isotropic_remeshing/examples/100071_sf.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"input": {
"edge_swap_mode": "valence",
"fix_uv_seam": false,
"input": {
"file": "100071_sf.msh",
"name_spec": "main"
},
"iterations": 30,
"length_abs": -1,
"length_rel": 0.01,
"lock_boundary": false,
"other_position_attributes": [
"vertices"
],
"output": {
"file": "100071_sf",
"type": ".vtu"
},
"position_attribute": "vertices",
"use_for_periodic": false
},
"stats": {
"main": {
"edges": 43536,
"faces": 29024,
"vertices": 14508
}
}
}
Loading
Loading