Closing shell of a Gyroid STL import

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
Konrad123
Posts: 4
Joined: Sun Jul 14, 2019 12:08 pm

Closing shell of a Gyroid STL import

Post by Konrad123 »

Hello everyone!

I have a problem closing a shell that I imported from a STL File.
First things first, I have to create a gyroid strukture for 3D-printing with python. I create the structure as Mesh using the marching_cubes_lewiner algorithm from skimage. You can see it in the picture:
Gyroid STL.png
Gyroid STL.png (57.22 KiB) Viewed 1439 times

The problem is, that the sides are open, so I can't convert it to a solid, only a shell is possible. As you can see in the pictures, the STL file has the information whether the surfaces are inside or outside (black is inside). By converting to a shell, it seems that I loose this information. My problem is now, that I have to find out which vertexes I have to connect to create faces to close the shell to get the solid. I hope, you understand what I mean by looking at the picture "Problem.png".
Shell.png
Shell.png (93.07 KiB) Viewed 1439 times
Problem.png
Problem.png (122.24 KiB) Viewed 1439 times

Is there a way to find out where these faces must be located by using the information stored in the mesh?
And how can I determine which vertexes I have to connect?

I have created these faces by hand using the shapebuilder in the example, I uploaded. But I have to get it done by a python macro for different STLs.
Compound.png
Compound.png (78 KiB) Viewed 1439 times

I'm very thankful for any ideas and help and please feel free to aks me for more Information you need.

You can find my .FCStd-file here: https://www.dropbox.com/s/txgyefkvyalbm ... FCStd?dl=0

FreeCad version:
OS: Windows 10
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.18.16117 (Git)
Build type: Release
Branch: (HEAD detached at 0.18.2)
Hash: dbb4cc6415bac848a294f03b80f65e888d531742
Python version: 3.7.1
Qt version: 5.6.2
Coin version: 4.0.0a
OCC version: 7.3.0
Locale: German/Germany (de_DE)
TheMarkster
Veteran
Posts: 5505
Joined: Thu Apr 05, 2018 1:53 am

Re: Closing shell of a Gyroid STL import

Post by TheMarkster »

Something to consider:

Convert the mesh to a shape (Part -> Create shape from mesh)
Get the boundbox: e.g. App.ActiveDocument.Gyroid_verschluss001.Shape.BoundBox
From the boundbox you can get the dimensions necessary for the next step
Create 6 part planes and position them so that one plane is coplanar with each of the size Edit: six sides
Fuse the planes into one fusion object
Get the boolean fragments for the fusion and the shape from the mesh (Select fusion and shape from mesh, Part -> Split -> Boolean Fragments)
Explode the boolean fragments (select fragments, Part -> Compound -> Explode)
Now the part that might require human intervention. Select from the fragments the shape from mesh and the fragments that would close the holes and use them to create a shell. This can be done with Part.makeShell(list of faces).
Create solid from the shell.
Create a mesh from the solid.

It might be you can filter the boolean fragments by area, for example: App.ActiveDocument.BooleanFragments_child0.Shape.Area

The one with the largest area is the original mesh. The ones with the smallest areas maybe are the ones that fill the holes.
ickby
Veteran
Posts: 3116
Joined: Wed Oct 05, 2011 7:36 am

Re: Closing shell of a Gyroid STL import

Post by ickby »

Annother idea, completely untested:
  • Find all edges that are shared only by 1 face (not so easy as freecad allowes only face->edge, not the other way around. maybe brute force?)
  • find the connected edges so you get all edges that form a wire
  • sort those edges (there is a part workbench function for that)
  • make faces from those wires
User avatar
brst
Posts: 87
Joined: Thu Apr 18, 2019 10:11 am
Location: Germany

Re: Closing shell of a Gyroid STL import

Post by brst »

You can try out Autodesk Meshmixer.
It's free and quite good for this task.
FreeCAD rookie
User avatar
brst
Posts: 87
Joined: Thu Apr 18, 2019 10:11 am
Location: Germany

Re: Closing shell of a Gyroid STL import

Post by brst »

Konrad123 wrote: Sun Jul 14, 2019 1:15 pm Hello everyone!

I have a problem closing a shell that I imported from a STL File.
First things first, I have to create a gyroid strukture for 3D-printing with python. I create the structure as Mesh using the marching_cubes_lewiner algorithm from skimage. You can see it in the picture:
Gyroid STL.png

The problem is, that the sides are open, so I can't convert it to a solid, only a shell is possible. As you can see in the pictures, the STL file has the information whether the surfaces are inside or outside (black is inside). By converting to a shell, it seems that I loose this information. My problem is now, that I have to find out which vertexes I have to connect to create faces to close the shell to get the solid. I hope, you understand what I mean by looking at the picture "Problem.png".
Shell.png
Problem.png

Is there a way to find out where these faces must be located by using the information stored in the mesh?
And how can I determine which vertexes I have to connect?

I have created these faces by hand using the shapebuilder in the example, I uploaded. But I have to get it done by a python macro for different STLs.
Compound.png

I'm very thankful for any ideas and help and please feel free to aks me for more Information you need.

You can find my .FCStd-file here: https://www.dropbox.com/s/txgyefkvyalbm ... FCStd?dl=0

FreeCad version:
OS: Windows 10
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.18.16117 (Git)
Build type: Release
Branch: (HEAD detached at 0.18.2)
Hash: dbb4cc6415bac848a294f03b80f65e888d531742
Python version: 3.7.1
Qt version: 5.6.2
Coin version: 4.0.0a
OCC version: 7.3.0
Locale: German/Germany (de_DE)
Afaik, gyroid infill is included in the Slicer Cura, so that might enough for your application.
FreeCAD rookie
Konrad123
Posts: 4
Joined: Sun Jul 14, 2019 12:08 pm

Re: Closing shell of a Gyroid STL import

Post by Konrad123 »

Thank you all for your quick replies!
brst wrote: Mon Jul 15, 2019 12:05 pm Afaik, gyroid infill is included in the Slicer Cura, so that might enough for your application.
Unfortunately, I can't use Cura because the thickness of the gyroid structure will vary locally to optimize the stability.
TheMarkster wrote: Mon Jul 15, 2019 3:14 am Something to consider:

Convert the mesh to a shape (Part -> Create shape from mesh)
Get the boundbox: e.g. App.ActiveDocument.Gyroid_verschluss001.Shape.BoundBox
From the boundbox you can get the dimensions necessary for the next step
Create 6 part planes and position them so that one plane is coplanar with each of the size Edit: six sides
Fuse the planes into one fusion object
Get the boolean fragments for the fusion and the shape from the mesh (Select fusion and shape from mesh, Part -> Split -> Boolean Fragments)
Explode the boolean fragments (select fragments, Part -> Compound -> Explode)
Now the part that might require human intervention. Select from the fragments the shape from mesh and the fragments that would close the holes and use them to create a shell. This can be done with Part.makeShell(list of faces).
Create solid from the shell.
Create a mesh from the solid.

It might be you can filter the boolean fragments by area, for example: App.ActiveDocument.BooleanFragments_child0.Shape.Area

The one with the largest area is the original mesh. The ones with the smallest areas maybe are the ones that fill the holes.
I like your idea very much, so I tried it today. Due to the density variation I managed to get a Gyroid that is nearly solid on the sides as you can see in the pictures. But I didn't explode the boolean fragments like you said. Instead I selected the six largest faces and made a shell out of them. The I made a compound with the shell and the original shell of the Gyroid and then created a solid from this compound.
The only problem remainig is, how to determin the 6 largest faces
The stl with high density
The stl with high density
stl.png (30.72 KiB) Viewed 1336 times
The result when I select the faces by hand
The result when I select the faces by hand
solid result.png (24.13 KiB) Viewed 1336 times
So it should be possible to find the 6 largest faces. But I don't know, how to compare the areas.
I know how to scroll through all the faces by using this line of code:

Code: Select all

for f in App.ActiveDocument.BooleanFragments.Shape.Faces:
But I don't know how to get the area of each of the faces because the line to get the area of one surface is for example:

Code: Select all

App.ActiveDocument.BooleanFragments.Shape.Face1.Area
I can't vary the "Face1" to something like "Face(i)", can I?
Or is there an other way to compare them?
TheMarkster
Veteran
Posts: 5505
Joined: Thu Apr 05, 2018 1:53 am

Re: Closing shell of a Gyroid STL import

Post by TheMarkster »

Konrad123 wrote: Mon Jul 15, 2019 4:08 pm
I like your idea very much, so I tried it today. Due to the density variation I managed to get a Gyroid that is nearly solid on the sides as you can see in the pictures. But I didn't explode the boolean fragments like you said. Instead I selected the six largest faces and made a shell out of them. The I made a compound with the shell and the original shell of the Gyroid and then created a solid from this compound.
The only problem remainig is, how to determin the 6 largest faces
stl.pngsolid result.png

So it should be possible to find the 6 largest faces. But I don't know, how to compare the areas.
I know how to scroll through all the faces by using this line of code:

Code: Select all

for f in App.ActiveDocument.BooleanFragments.Shape.Faces:
But I don't know how to get the area of each of the faces because the line to get the area of one surface is for example:

Code: Select all

App.ActiveDocument.BooleanFragments.Shape.Face1.Area
I can't vary the "Face1" to something like "Face(i)", can I?
Or is there an other way to compare them?
You can generate the strings, e.g. "Face1", "Face2", for example (untested) :

Code: Select all

for f in range(1,10):
   f_str = "Face"+str(f)
   obj = getattr(App.ActiveDocument.BooleanFragments.Shape,f_str)
   area = obj.Area
Konrad123
Posts: 4
Joined: Sun Jul 14, 2019 12:08 pm

Re: Closing shell of a Gyroid STL import

Post by Konrad123 »

TheMarkster wrote: Mon Jul 15, 2019 6:06 pm
Konrad123 wrote: Mon Jul 15, 2019 4:08 pm
I like your idea very much, so I tried it today. Due to the density variation I managed to get a Gyroid that is nearly solid on the sides as you can see in the pictures. But I didn't explode the boolean fragments like you said. Instead I selected the six largest faces and made a shell out of them. The I made a compound with the shell and the original shell of the Gyroid and then created a solid from this compound.
The only problem remainig is, how to determin the 6 largest faces
stl.pngsolid result.png

So it should be possible to find the 6 largest faces. But I don't know, how to compare the areas.
I know how to scroll through all the faces by using this line of code:

Code: Select all

for f in App.ActiveDocument.BooleanFragments.Shape.Faces:
But I don't know how to get the area of each of the faces because the line to get the area of one surface is for example:

Code: Select all

App.ActiveDocument.BooleanFragments.Shape.Face1.Area
I can't vary the "Face1" to something like "Face(i)", can I?
Or is there an other way to compare them?
You can generate the strings, e.g. "Face1", "Face2", for example (untested) :

Code: Select all

for f in range(1,10):
   f_str = "Face"+str(f)
   obj = getattr(App.ActiveDocument.BooleanFragments.Shape,f_str)
   area = obj.Area
Thank you very much, that worked perfectly!
Konrad123
Posts: 4
Joined: Sun Jul 14, 2019 12:08 pm

Re: Closing shell of a Gyroid STL import

Post by Konrad123 »

Hi
I have another problem now :(
I wanted to use my concept on a larger and more complex model. It worked very well (except for the computing time) until the step where I sliced the planes into fragments. It seems that a few wires aren't closed, so the some faces can't be determined.
Problem.png
Problem.png (6.03 KiB) Viewed 1263 times
Does anyone know, how to determine where the gaps are and how to close them?
Or is something else the problem?
I've uploaded the file here: https://www.dropbox.com/s/bsyzfeupjhytu ... FCStd?dl=0

Thank you all for your ideas, you are helping a lot!
User avatar
DeepSOIC
Veteran
Posts: 7896
Joined: Fri Aug 29, 2014 12:45 am
Location: used to be Saint-Petersburg, Russia

Re: Closing shell of a Gyroid STL import

Post by DeepSOIC »

Konrad123 wrote: Thu Jul 18, 2019 7:17 pm Does anyone know, how to determine where the gaps are and how to close them?
Try messing with Tolerance property.
Post Reply