Home › Forum › SOFA › Getting Started › [SOLVED] How to use the Sofa mesh partition tools?
- This topic has 14 replies, 3 voices, and was last updated 4 years, 6 months ago by Pasquale94.
-
AuthorPosts
-
9 May 2020 at 21:07 #16138Pasquale94Blocked
Hi everyone again, I am sorry if I make a lot of post and questions in these days.
One of my projects consist into simulate a pneumatic finger, made up of two different materials. In particular the overall structure, can be devided in a bottom part made by one material, and an upper part, which is made by a different one.
Of course, I have the surface mesh (file .obj) and the tetrahedral one (file .vtu).
I downloaded from the marketplace the “SOFA_mesh_partitioning_tools”(made by the CSIRO in Australia), and there some things that are not clear for me, because i am very new in mesh generation and partition.
First of all, i am following the file README.md, and I arrived at the point when the python script “test_mesh_generator_python2.py” have to be activated. When I try to call it in the command line, there is this following error, which i don’t understand why:['openscad', '-osphere_0_0_skin.off', '-Dx=0', '-Dy=0', '-Dz=0', 'movable_sphere2.scad'] Traceback (most recent call last): File "test_mesh_generator_python2.py", line 13, in <module> subprocess.call(openscad_cmd.split()) File "/usr/lib/python2.7/subprocess.py", line 172, in call return Popen(*popenargs, **kwargs).wait() File "/usr/lib/python2.7/subprocess.py", line 394, in __init__ errread, errwrite) File "/usr/lib/python2.7/subprocess.py", line 1047, in _execute_child raise child_exception OSError: [Errno 2] No such file or directory
How can I resolve? What is the function of this code?
Then, when I type from the folder “Mesh_pipeline_exact_src” the command
./pipeline2 -i input_files_dir/input_files_demo/ -o output_files_dir/output_files_demo
this error will appear :
Input directory was set to input_files_dir/input_files_demo/. Output directory was set to output_files_dir/output_files_demo. prog_opts() done "input_files_dir/input_files_demo/"is not a directory tissues.size() = 0 segmentation fault (core dump created)
How can I fix it?
Then, seeing the examples, demo.scn and the finger_edited.py, I understood that my case, is closer to the application of the first scene, that plays with the local stiffness factors, but what I don’t uderstand how to make the mesh partitioning. Someone can guide me into do this?
14 May 2020 at 22:56 #16238HugoKeymasterDear @pasquale94
Many questions mean many investigation ongoing with SOFA! That’s good!
Since your question concerns the work from CSIRO and that I am not familiar with it (and apparently some error related to ‘openscad’), let me add Dr. Hockings to the discussions @NickHockingsBest
Hugo
15 May 2020 at 01:16 #16251NickHockBlockedHello @pasquale94
looking at the error messages, my first question is : do you have OpenSCAD installed ?
It is cross-platform and free-and-open-source, available here http://www.openscad.org/downloads.html .Explanation:
The python script makes calls to OpenSCAD, to generate the set of intersecting surface meshes used in the demo.Edit: I have just spotted that the file “movable_sphere2.scad” is missing from the repository. It is just the following OpenSCAD script:
module movable_sphere2()
{
translate([x,y,z])
sphere(20, $fs = 0.01);
}movable_sphere2();
Please let me know how you get on.
Best,
Nick15 May 2020 at 10:39 #16259Pasquale94BlockedThank you @nickhockings and @Hugo,
I resolved the first error but the second not. How is possible that it not find the input folder?
Thank you,
Pasquale16 May 2020 at 00:33 #16297NickHockBlocked@pasquale94,
It is looking for the input folder using a relative path from where “pipeline2” is run. Two ways it might not find the input folder (i) does the folder exist, (ii) is the relative path correct for where you are running the script.In the Git repository “SOFA_mesh_partitioning_tools/mesh_pipeline/input_files_dir/input_files_demo/” is already populated with the input files (identical to what would be produced by the “test_mesh_generator_python2.py” script). The instructions imply that you would be in the “SOFA_mesh_partitioning_tools/mesh_pipeline/” directory when calling “Mesh_pipeline_exact_src/pipeline2 -i input_files_dir/input_files_demo/ -o output_files_dir/output_files_demo”
Best,
Nick17 May 2020 at 01:38 #16301Pasquale94BlockedThank you for the explanation, but now I encountered another error:
terminate called after throwing an instance of 'CGAL::Assertion_exception' what(): CGAL ERROR: assertion violation! Expr: !tree_.empty() File: /usr/local/include/CGAL/Polyhedral_mesh_domain_3.h Line: 730 Annullato (core dump creato)
It seems that the variable “tree_” is empty. How can I fix it?
17 May 2020 at 09:39 #16304NickHockBlockedHi @pasquale94,
tree_ is internal to CGAL. The problem will be further back in the execution.
Please send me all the terminal output from where you called
Mesh_pipeline_exact_src/pipeline2 -i input_files_dir/input_files_demo/ -o output_files_dir/output_files_demo
…
The main program prints out statements as each section completes.
I need to see these and the whole stack of errors that it gives you.
Best regards,
Nick17 May 2020 at 12:10 #16305Pasquale94BlockedHello @NickHockings
I called the command
Mesh_pipeline_exact_src/pipeline2 -i input_files_dir/input_files_demo/ -o output_files_dir/output_files_demo
from the folder SOFA_mesh_partitioning_tools-master/mesh_pipeline, this is the output of the terminal:Mesh_pipeline_exact_src/pipeline2 -i input_files_dir/input_files_demo/ -o output_files_dir/output_files_demo Input directory was set to input_files_dir/input_files_demo/. Output directory was set to output_files_dir/output_files_demo. prog_opts() done "input_files_dir/input_files_demo/" is a directory containing: it->filename() : movable_sphere2_25_0_0_skin.off it->filename() : sphere_0_0_s_kin.off it->filename() : sphere_0_10_skin.off it->filename() : sphere_0_30_skin.off it->filename() : sphere_10_0_bone.off it->filename() : sphere_10_10_bone.off it->filename() : sphere_10_30_bone.off it->filename() : sphere_20_30_tendon.off it->filename() : sphere_30_30_ligament.off it->filename() : tissues.yaml Reading a yaml file Adding : skin 10 tissues.size() : 1 Adding : bone 1000 tissues.size() : 2 Adding : tendon 100 tissues.size() : 3 Adding : ligament 100 tissues.size() : 4 Adding : muscle 10 tissues.size() : 5 Adding : loose_ct 1 tissues.size() : 6 "input_files_dir/input_files_demo/" : Reading meshes "input_files_dir/input_files_demo/movable_sphere2_25_0_0_skin.off" s = movable_sphere2_25_0_0_skin.off e = .*skin.* pushing back skin->mesh_vec.size() = 1 s = movable_sphere2_25_0_0_skin.off e = .*bone.* s = movable_sphere2_25_0_0_skin.off e = .*tendon.* s = movable_sphere2_25_0_0_skin.off e = .*ligament.* s = movable_sphere2_25_0_0_skin.off e = .*muscle.* s = movable_sphere2_25_0_0_skin.off e = .*loose_ct.* "input_files_dir/input_files_demo/sphere_0_0_s_kin.off" s = sphere_0_0_s_kin.off e = .*skin.* s = sphere_0_0_s_kin.off e = .*bone.* s = sphere_0_0_s_kin.off e = .*tendon.* s = sphere_0_0_s_kin.off e = .*ligament.* s = sphere_0_0_s_kin.off e = .*muscle.* s = sphere_0_0_s_kin.off e = .*loose_ct.* "input_files_dir/input_files_demo/sphere_0_10_skin.off" s = sphere_0_10_skin.off e = .*skin.* pushing back skin->mesh_vec.size() = 2 s = sphere_0_10_skin.off e = .*bone.* s = sphere_0_10_skin.off e = .*tendon.* s = sphere_0_10_skin.off e = .*ligament.* s = sphere_0_10_skin.off e = .*muscle.* s = sphere_0_10_skin.off e = .*loose_ct.* "input_files_dir/input_files_demo/sphere_0_30_skin.off" s = sphere_0_30_skin.off e = .*skin.* pushing back skin->mesh_vec.size() = 3 s = sphere_0_30_skin.off e = .*bone.* s = sphere_0_30_skin.off e = .*tendon.* s = sphere_0_30_skin.off e = .*ligament.* s = sphere_0_30_skin.off e = .*muscle.* s = sphere_0_30_skin.off e = .*loose_ct.* "input_files_dir/input_files_demo/sphere_10_0_bone.off" s = sphere_10_0_bone.off e = .*skin.* s = sphere_10_0_bone.off e = .*bone.* pushing back bone->mesh_vec.size() = 1 s = sphere_10_0_bone.off e = .*tendon.* s = sphere_10_0_bone.off e = .*ligament.* s = sphere_10_0_bone.off e = .*muscle.* s = sphere_10_0_bone.off e = .*loose_ct.* "input_files_dir/input_files_demo/sphere_10_10_bone.off" s = sphere_10_10_bone.off e = .*skin.* s = sphere_10_10_bone.off e = .*bone.* pushing back bone->mesh_vec.size() = 2 s = sphere_10_10_bone.off e = .*tendon.* s = sphere_10_10_bone.off e = .*ligament.* s = sphere_10_10_bone.off e = .*muscle.* s = sphere_10_10_bone.off e = .*loose_ct.* "input_files_dir/input_files_demo/sphere_10_30_bone.off" s = sphere_10_30_bone.off e = .*skin.* s = sphere_10_30_bone.off e = .*bone.* pushing back bone->mesh_vec.size() = 3 s = sphere_10_30_bone.off e = .*tendon.* s = sphere_10_30_bone.off e = .*ligament.* s = sphere_10_30_bone.off e = .*muscle.* s = sphere_10_30_bone.off e = .*loose_ct.* "input_files_dir/input_files_demo/sphere_20_30_tendon.off" s = sphere_20_30_tendon.off e = .*skin.* s = sphere_20_30_tendon.off e = .*bone.* s = sphere_20_30_tendon.off e = .*tendon.* pushing back tendon->mesh_vec.size() = 1 s = sphere_20_30_tendon.off e = .*ligament.* s = sphere_20_30_tendon.off e = .*muscle.* s = sphere_20_30_tendon.off e = .*loose_ct.* "input_files_dir/input_files_demo/sphere_30_30_ligament.off" s = sphere_30_30_ligament.off e = .*skin.* s = sphere_30_30_ligament.off e = .*bone.* s = sphere_30_30_ligament.off e = .*tendon.* s = sphere_30_30_ligament.off e = .*ligament.* pushing back ligament->mesh_vec.size() = 1 s = sphere_30_30_ligament.off e = .*muscle.* s = sphere_30_30_ligament.off e = .*loose_ct.* "input_files_dir/input_files_demo/tissues.yaml" Not a .off file "input_files_dir/input_files_demo/tissues.yaml" Finished reading meshed tissues.size() = 6 tissues.begin()->name = skin tissues.begin()->mesh_vec.size() = 3 load_surface_meshes() done out_dir = output_files_dir/output_files_demo "output_files_dir/output_files_demo"is not a directory subdomain_meshes.begin()->mesh_vec.begin()->is_empty() = 0 tissue_it_a = 0 tissue_it_d = 1 tissue_it_d = 2 tissue_it_d = 3 target patch : 1_0 tissue_it_a = 1 tissue_it_b = 0 tissue_it_c = 0 continue target.mesh_vec.at(1).is_empty() = 0 target patch : 1_2 tissue_it_d = 0 tissue_it_d = 2 tissue_it_d = 3 target patch : 2_0 tissue_it_a = 2 tissue_it_b = 0 tissue_it_c = 0 continue tissue_it_c = 1target.mesh_vec.at(1).is_empty() = 0 target patch : 1_3 tissue_it_b = 1 tissue_it_c = 0 tissue_it_c = 1 continue target.mesh_vec.at(1).is_empty() = 0 target patch : 2_3 tissue_it_d = 0 tissue_it_d = 1 tissue_it_d = 3 target patch : 3_0 tissue_it_a = 3 tissue_it_b = 0 tissue_it_c = 0 continue tissue_it_c = 1 tissue_it_c = 2target.mesh_vec.at(1).is_empty() = 0 target patch : 1_4 tissue_it_b = 1 tissue_it_c = 0 tissue_it_c = 1 continue tissue_it_c = 2target.mesh_vec.at(1).is_empty() = 0 tissue_it_b = 2 tissue_it_c = 0 tissue_it_c = 1 tissue_it_c = 2 continue target.mesh_vec.at(1).is_empty() = 0 target patch : 3_4 tissue_it_d = 0 tissue_it_d = 1 tissue_it_d = 2 target patch : 4_0 generate_subdomain_meshes() done idx = 0, new_pair_vec.size() = 2 idx = 1, new_pair_vec.size() = 3 idx = 2, new_pair_vec.size() = 4 idx = 3, new_pair_vec.size() = 5 idx = 4, new_pair_vec.size() = 6 idx = 5, new_pair_vec.size() = 7 idx = 6, new_pair_vec.size() = 8 idx = 7, new_pair_vec.size() = 9 idx = 8, new_pair_vec.size() = 10 pair_vec[0] = (1,0) pair_vec[1] = (1,2) pair_vec[2] = (2,0) pair_vec[3] = (1,3) pair_vec[4] = (2,3) pair_vec[5] = (3,0) pair_vec[6] = (1,4) pair_vec[7] = (3,4) pair_vec[8] = (4,0) new_pair_vec[0] = (1,0) new_pair_vec[1] = (1,0) new_pair_vec[2] = (1,2) new_pair_vec[3] = (2,0) new_pair_vec[4] = (1,3) new_pair_vec[5] = (2,3) new_pair_vec[6] = (3,0) new_pair_vec[7] = (1,4) new_pair_vec[8] = (3,4) new_pair_vec[9] = (4,0) mkvec_cc() done patch_vec.size() = 10 pair_vec.size() = 10 Wrote filename :output_files_dir/output_files_demo/patch0.off i=0 patch_vec.at(i).is_valid() = 1 patch_vec.at(i).is_empty() = 0 patch_vec.at(i).number_of_faces 1201 patches.at(i).is_valid() = 1 patches.at(i).is_empty() = 1 patches.at(i).size_of_facets() = 0 patches.at(i) num facets = 0 patch_vec.at(i).number_of_faces 1201 Wrote filename :output_files_dir/output_files_demo/patch1.off i=1 patch_vec.at(i).is_valid() = 1 patch_vec.at(i).is_empty() = 0 patch_vec.at(i).number_of_faces 764 patches.at(i).is_valid() = 1 patches.at(i).is_empty() = 1 patches.at(i).size_of_facets() = 0 patches.at(i) num facets = 0 patch_vec.at(i).number_of_faces 764 Wrote filename :output_files_dir/output_files_demo/patch2.off i=2 patch_vec.at(i).is_valid() = 1 patch_vec.at(i).is_empty() = 0 patch_vec.at(i).number_of_faces 1131 patches.at(i).is_valid() = 1 patches.at(i).is_empty() = 1 patches.at(i).size_of_facets() = 0 patches.at(i) num facets = 0 patch_vec.at(i).number_of_faces 1131 Wrote filename :output_files_dir/output_files_demo/patch3.off i=3 patch_vec.at(i).is_valid() = 1 patch_vec.at(i).is_empty() = 0 patch_vec.at(i).number_of_faces 1398 patches.at(i).is_valid() = 1 patches.at(i).is_empty() = 1 patches.at(i).size_of_facets() = 0 patches.at(i) num facets = 0 patch_vec.at(i).number_of_faces 1398 Wrote filename :output_files_dir/output_files_demo/patch4.off i=4 patch_vec.at(i).is_valid() = 1 patch_vec.at(i).is_empty() = 0 patch_vec.at(i).number_of_faces 96 patches.at(i).is_valid() = 1 patches.at(i).is_empty() = 1 patches.at(i).size_of_facets() = 0 patches.at(i) num facets = 0 patch_vec.at(i).number_of_faces 96 Wrote filename :output_files_dir/output_files_demo/patch5.off i=5 patch_vec.at(i).is_valid() = 1 patch_vec.at(i).is_empty() = 0 patch_vec.at(i).number_of_faces 415 patches.at(i).is_valid() = 1 patches.at(i).is_empty() = 1 patches.at(i).size_of_facets() = 0 patches.at(i) num facets = 0 patch_vec.at(i).number_of_faces 415 Wrote filename :output_files_dir/output_files_demo/patch6.off i=6 patch_vec.at(i).is_valid() = 1 patch_vec.at(i).is_empty() = 0 patch_vec.at(i).number_of_faces 431 patches.at(i).is_valid() = 1 patches.at(i).is_empty() = 1 patches.at(i).size_of_facets() = 0 patches.at(i) num facets = 0 patch_vec.at(i).number_of_faces 431 Wrote filename :output_files_dir/output_files_demo/patch7.off i=7 patch_vec.at(i).is_valid() = 1 patch_vec.at(i).is_empty() = 0 patch_vec.at(i).number_of_faces 118 patches.at(i).is_valid() = 1 patches.at(i).is_empty() = 1 patches.at(i).size_of_facets() = 0 patches.at(i) num facets = 0 patch_vec.at(i).number_of_faces 118 Wrote filename :output_files_dir/output_files_demo/patch8.off i=8 patch_vec.at(i).is_valid() = 1 patch_vec.at(i).is_empty() = 0 patch_vec.at(i).number_of_faces 362 patches.at(i).is_valid() = 1 patches.at(i).is_empty() = 1 patches.at(i).size_of_facets() = 0 patches.at(i) num facets = 0 patch_vec.at(i).number_of_faces 362 Wrote filename :output_files_dir/output_files_demo/patch9.off i=9 patch_vec.at(i).is_valid() = 1 patch_vec.at(i).is_empty() = 0 patch_vec.at(i).number_of_faces 696 patches.at(i).is_valid() = 1 patches.at(i).is_empty() = 1 patches.at(i).size_of_facets() = 0 patches.at(i) num facets = 0 patch_vec.at(i).number_of_faces 696 pair_vec[0] = (1,0) pair_vec[1] = (1,0) pair_vec[2] = (1,2) pair_vec[3] = (2,0) pair_vec[4] = (1,3) pair_vec[5] = (2,3) pair_vec[6] = (3,0) pair_vec[7] = (1,4) pair_vec[8] = (3,4) pair_vec[9] = (4,0) Generating domain terminate called after throwing an instance of 'CGAL::Assertion_exception' what(): CGAL ERROR: assertion violation! Expr: !tree_.empty() File: /usr/local/include/CGAL/Polyhedral_mesh_domain_3.h Line: 730 Annullato (core dump creato)
Thank you for the support,
Pasquale.
17 May 2020 at 12:28 #16306NickHockBlockedHi @pasquale94
I think the fault is here :
out_dir = output_files_dir/output_files_demo
“output_files_dir/output_files_demo”is not a directory
subdomain_meshes.begin()->mesh_vec.begin()->is_empty() = 0You need to create the directory “output_files_dir/output_files_demo”.
(This is partly because Git does not like me leaving an empty directory in the repository.)Best regards,
Nick17 May 2020 at 18:16 #16307Pasquale94BlockedThank you for the support! It works now… But I still have a question.
I want to make a mesh partition of a soft robotic finger, because it is made by two different material. So, my question is, How to do that, how I can differentiate the domains that I want in the mesh? And then, I have to do this with the surface mesh or the volumetric one?I am sorry fo all this question, but I am very new in this field.
Happy Sunday!Pasquale.
18 May 2020 at 00:06 #16308NickHockBlockedHi @pasquale94,
Good to hear that you have it working now.
Short answer:
The domains are differentiated by keywords in their file names, defined in the .yaml file. The input files need to be .off surface meshes.Long Answer:
The way that it works is that it takes in a set of surface meshes, and uses them to define the partitioned tetrahedral mesh that it generates.
The surface meshes are divided into one group for each material. A surface mesh is identified as belonging to a particular material by the keyword at the end of its filename. e.g. “myFirstMesh_bone.ply” and “mySecondMesh_bone.ply” are both in the “bone” group. The members of each group are ‘union’ed to make a single surface mesh for each material.
These surface meshes defining each material are the subtracted from each other in order of precedence. The keywords of the materials and their order of precedence is defined in the .yaml file. The result of this step is a set of surface patch meshes that define the boundaries between each material.
The final step uses these patches to generate the partitioned tetrahedral mesh.
Note there are “mesh specification options” that define qualities of the tetrahedral mesh, including element size and facet angle. The right values depend on the scale of your input meshes, and the resolution you desire for the partitioned tetrahedral mesh.After that you need to follow the “Building a SOFA scene with a partitioned mesh:” instructions. Look at the “multi-stiffness_FEM_demo\demo.scn” file to see how the partitioned mesh is used, and don’t forget to do the “Manual editing of .vtu file xml tags 64bit -> 32bit”.
Best regards,
Nick18 May 2020 at 18:19 #16317Pasquale94BlockedThank you for all the support, noe I understand and all my doubts are clear, I alo created my partitioned mesh and everything works. Thank you very much!
Best,
Pasquale.19 May 2020 at 00:30 #16318NickHockBlockedHi @pasquale94,
That’s great to hear. Please send screen shots and videos to @hugo. He is always looking for images for the SOFA gallery. NB the SOFA GUI has options for capturing video.
Best,
Nick19 May 2020 at 09:38 #16321HugoKeymasterOuh yeah! Do not hesitate to send me videos so that I can highlight both of your work!
Congrats @pasquale94 and @NickHockings for helping so much!Hugo
19 May 2020 at 14:32 #16322Pasquale94BlockedHello @NickHockings and @Hugo.
The projects are at an early stage for now, but in the next months we have other results, and our group is growing, so of course we will send you our highlights and material.
Thank you for the interest!
Best,
Pasquale Ferrentino. -
AuthorPosts
- You must be logged in to reply to this topic.