Vedo 3D-Gyroid structures STL export

411 Views Asked by At

I need to generate a double 3D gyroid structure. For this, I'm using vedo

from matplotlib import pyplot as plt
from scipy.constants import speed_of_light
from vedo import *
import numpy as np

# Paramters
a = 5
length = 100
width = 100
height = 10

pi = np.pi

x, y, z = np.mgrid[:length, :width, :height]

def gen_strut(start, stop):
    '''Generate the strut parameter t for the gyroid surface. Create a linear gradient'''
    strut_param = np.ones((length, 1))
    strut_param = strut_param * np.linspace(start, stop, width)
    t = np.repeat(strut_param[:, :, np.newaxis], height, axis=2)
    return t

plt = Plotter(shape=(1, 1), interactive=False, axes=3)


scale=0.5
cox = cos(scale * pi * x / a)
siy = sin(scale * pi * y / a)
coy = cos(scale * pi * y / a)
siz = sin(scale * pi * z / a)
coz = cos(scale * pi * z / a)
six = sin(scale * pi * x / a)
U1 = ((six ** 2) * (coy ** 2) +
      (siy ** 2) * (coz ** 2) +
      (siz ** 2) * (cox ** 2) +
      (2 * six * coy * siy * coz) +
      (2 * six * coy * siz * cox) +
      (2 * cox * siy * siz * coz)) - (gen_strut(0, 1.3) ** 2)

threshold = 0
iso1 = Volume(U1).isosurface(threshold).c('silver').alpha(1)
cube = TessellatedBox(n=(int(length-1), int(width-1), int(height-1)), spacing=(1, 1, 1))
iso_cut = cube.cutWithMesh(iso1).c('silver').alpha(1)
# Combine the two meshes into a single mesh

plt.at(0).show([cube, iso1], "Double Gyroid 1", resetcam=False)
plt.interactive().close()

Gyroid Structure

The result looks quite good, but now I'm struggling with exporting the volume. Although vedo has over 300 examples, I did not find anything in the documentation to export this as a watertight volume for 3D-Printing. How can I achieve this?

1

There are 1 best solutions below

1
On BEST ANSWER

I assume you mean that you want to extract a watertight mesh as an STL (?). This is a non trivial problem because it is only well defined on a subset of the mesh regions where the in/out is not ambiguous, in those cases fill_holes() seems to do a decent job.. Other cases should be dealt "manually". Eg, you can access the boundaries with mesh.boundaries() and try to snap the vertices to a closest common vertex. This script is not a solution, but I hope can give some ideas on how to proceed.

from vedo import *

# Paramters
a = 5
length = 100
width = 100
height = 10

def gen_strut(start, stop):
    strut_param = np.ones((length, 1))
    strut_param = strut_param * np.linspace(start, stop, width)
    t = np.repeat(strut_param[:, :, np.newaxis], height, axis=2)
    return t

scale=0.5
pi = np.pi
x, y, z = np.mgrid[:length, :width, :height]
cox = cos(scale * pi * x / a)
siy = sin(scale * pi * y / a)
coy = cos(scale * pi * y / a)
siz = sin(scale * pi * z / a)
coz = cos(scale * pi * z / a)
six = sin(scale * pi * x / a)
U1 = ((six ** 2) * (coy ** 2) +
      (siy ** 2) * (coz ** 2) +
      (siz ** 2) * (cox ** 2) +
      (2 * six * coy * siy * coz) +
      (2 * six * coy * siz * cox) +
      (2 * cox * siy * siz * coz)) - (gen_strut(0, 1.3) ** 2)

iso = Volume(U1).isosurface(0).c('silver').backcolor("p5").lw(1).flat()
cube = TessellatedBox(n=(length-1, width-1, height-1)).c('red5').alpha(1)
cube.triangulate().compute_normals()
cube.cut_with_mesh(iso).compute_normals()

print(iso.boundaries(return_point_ids=True))
print(cube.boundaries(return_point_ids=True))
print(iso.boundaries().join().lines())

show(iso, cube).close()
merge(iso, cube).clean().backcolor("p5").show().close()
iso.clone().fill_holes(15).backcolor("p5").show().close()

enter image description here