Save `pyvista.MultiBlock` in STL format
See original GitHub issueHello everyone.
I think that the option to save the pyvista.MultiBlock
type in STL format would be helpful. Various software (e.g., Beta Ansa preprocessing tool for Computational Fluid Dynamics or Meshmixer) only accepts STL format for the input geometry. Multiple parts are allowed in the STL format by adding the solid [solid_name] .... endsolid [solid_name]
keywords. This is an example (for STL ASCII, of course):
solid "front"
facet normal -0.161384269595 0.98523491621 -0.0571600198746
outer loop
vertex 2.43927001953 -3.28291988373 31.002199173
vertex 2.58858990669 -4.39023017883 31.0909004211
vertex 3.39857983589 -3.73215985298 31.1854000092
endloop
endfacet
facet normal -0.0869731009007 0.839549422264 -0.536276459694
outer loop
vertex 3.77996993065 1.47368001938 29.9706001282
vertex 4.10769987106 2.22097992897 29.5272006989
vertex 3.07201004028 2.18530011177 29.4426994324
endloop
endfacet
.........
endsolid "front"
solid "back"
facet normal 0.348130375147 0.823633670807 0.447697281837
outer loop
vertex 10.0833997726 -10.0583000183 29.6856994629
vertex 10.8774995804 -9.29601955414 29.7644004822
vertex 9.88414001465 -9.12524032593 30.2770996094
endloop
endfacet
facet normal -0.140576228499 0.74150198698 0.6560587883
outer loop
vertex 3.84086990356 -11.9118995667 28.7719993591
vertex 3.13609004021 -11.3332004547 29.1504001617
vertex 2.98072004318 -12.218000412 28.3381004333
endloop
endfacet
.........
endsolid "back"
I came up with a temporary solution using the already present function to save individual pyvista.PolyData
in STL format:
def save_multiblock_stl(multiblock, filename):
names = multiblock.keys()
oname, ext = osp.splitext(filename)
assert ext == '.stl'
# each individual stl file saved (output_filenames)
ofiles = [f'{oname}_{ii}' + '.stl' for ii in range(len(names))]
for ii, subpart in enumerate(multiblock):
subpart.save(ofiles[ii], binary=False)
change_first_line_of_file(ofiles[ii], f'solid {names[ii]}') # basically changes "solid" to "solid <solid_name>"
# merge files together
total_stl = ''
for fn in ofiles:
f = open(fn)
total_stl += f.read()
f.close()
# writes total stl file
with open(oname + '.stl', 'w') as f:
f.write(total_stl)
# deletes previously written stl files
for fn in ofiles:
os.remove(fn)
return
def change_first_line_of_file(filename, new_first_line):
fr = open(filename, 'r')
first_line = fr.readline()
fr.close()
first_line_len = len(first_line)
new_first_line_len = len(new_first_line)
spaces_num = first_line_len - new_first_line_len
new_first_line = new_first_line + ' '*(spaces_num-1) + '\n'
fw = StringIO(new_first_line)
fr = open(filename, 'r+')
shutil.copyfileobj(fw, fr)
fr.close()
fw.close()
return
Basically, I write to disk in STL ascii every single part of the pyvista.MultiBlock
, I change the first line of each file from “solid” to “solid <solid_name>” and then I merge the files together. This works because the syntax
solid <solid_name>
...
...
endsolid
is allowed.
Obviously, this is not an efficient solution, so maybe someone has a better idea.
Thanks !
Issue Analytics
- State:
- Created 2 years ago
- Comments:13 (7 by maintainers)
Top GitHub Comments
Thank you for your reply! Actually, I’m not familiar with vtk alone. I could paste this same post in their forum at https://discourse.vtk.org/c/development/7/l/latest. What do you think?
Ok, thanks very much for the explanation.
I think you convinced me. Adding this option in the vtk library would not be a good solution.
If I was the only one interested, I will close the issue.