generate mesh inside .STL file

I have some STL files (usually aneurysm) and I'm using Lattice Boltzmann Method for my simulation and I need to construct the mesh. As far as LBM uses cubic mesh structure (in 3D) and STL file is giving bunch of triangles for surface (boundary) I'm a little confused on how I can construct the mesh based on the STL information. I already used the code https://www.cplusplus.com/forum/beginner/278645/#msg1203789 and it works fine. It generate some geometries and generate STL file, but I'm looking for something the uses my own STL file and generate the mesh based on the information provided by the STL. Also the curvature boundary of vessels make it a little bit more complex for me.
I strongly appreciate any idea.
Last edited on
Well, you can google "mesh generator software". Gmsh might help you, but I've never used it myself. You need software that (a) will import STL files (which, to be fair, most do); (b) exports a volume mesh that your own CFD software can use.

All the STL file gives you is a triangulated representation of the bounding surface - it doesn't fill in the volume mesh in between. For that you will have to find - or maybe write - a proper mesh generator.

I don't use the Lattice Boltzmann Method - I'd rather use standard finite-volume CFD any day - but I don't think it is restricted to cubic lattices.
Last edited on
More information required, please.
- Mainly I don't know where you are in the process, where is your hang-up?
* the triangles should directly define your verteces, do they not?
* is it binary or ascii STL?
- It sounds like you are the one who generated the STL, can you open it using Blender or other 3d editor to confirm correct output?
- What is the goal with the data (output to screen/file?)
* if file output is the goal, then what format?

Here's Blender's default cube exported to a stl (ascii)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
solid Exported from Blender-3.0.1
facet normal 0.000000 0.000000 1.000000
outer loop
vertex 1.000000 1.000000 1.000000
vertex -1.000000 1.000000 1.000000
vertex -1.000000 -1.000000 1.000000
endloop
endfacet
facet normal 0.000000 0.000000 1.000000
outer loop
vertex 1.000000 1.000000 1.000000
vertex -1.000000 -1.000000 1.000000
vertex 1.000000 -1.000000 1.000000
endloop
endfacet
facet normal 0.000000 -1.000000 0.000000
outer loop
vertex 1.000000 -1.000000 -1.000000
vertex 1.000000 -1.000000 1.000000
vertex -1.000000 -1.000000 1.000000
endloop
endfacet
facet normal 0.000000 -1.000000 0.000000
outer loop
vertex 1.000000 -1.000000 -1.000000
vertex -1.000000 -1.000000 1.000000
vertex -1.000000 -1.000000 -1.000000
endloop
endfacet
facet normal -1.000000 0.000000 0.000000
outer loop
vertex -1.000000 -1.000000 -1.000000
vertex -1.000000 -1.000000 1.000000
vertex -1.000000 1.000000 1.000000
endloop
endfacet
facet normal -1.000000 0.000000 0.000000
outer loop
vertex -1.000000 -1.000000 -1.000000
vertex -1.000000 1.000000 1.000000
vertex -1.000000 1.000000 -1.000000
endloop
endfacet
facet normal 0.000000 0.000000 -1.000000
outer loop
vertex -1.000000 1.000000 -1.000000
vertex 1.000000 1.000000 -1.000000
vertex 1.000000 -1.000000 -1.000000
endloop
endfacet
facet normal 0.000000 0.000000 -1.000000
outer loop
vertex -1.000000 1.000000 -1.000000
vertex 1.000000 -1.000000 -1.000000
vertex -1.000000 -1.000000 -1.000000
endloop
endfacet
facet normal 1.000000 0.000000 0.000000
outer loop
vertex 1.000000 1.000000 -1.000000
vertex 1.000000 1.000000 1.000000
vertex 1.000000 -1.000000 1.000000
endloop
endfacet
facet normal 1.000000 0.000000 0.000000
outer loop
vertex 1.000000 1.000000 -1.000000
vertex 1.000000 -1.000000 1.000000
vertex 1.000000 -1.000000 -1.000000
endloop
endfacet
facet normal 0.000000 1.000000 0.000000
outer loop
vertex -1.000000 1.000000 -1.000000
vertex -1.000000 1.000000 1.000000
vertex 1.000000 1.000000 1.000000
endloop
endfacet
facet normal 0.000000 1.000000 0.000000
outer loop
vertex -1.000000 1.000000 -1.000000
vertex 1.000000 1.000000 1.000000
vertex 1.000000 1.000000 -1.000000
endloop
endfacet
endsolid Exported from Blender-3.0.1


Everything is triangles. 12 triangles to define the 6 square sides. But if you modify one vertex in blender, how many vertex change in the STL?
Pretty sure the answer you are looking for is to collect all the STL "vertex" that are equal in the data and provide a handle to each of those as modifiable points (modifying a handle should modify all of those equivalent vertex). How you define and store a handle is up to you, but I would use a vector of pointers to vertex objects. Each index in that vector would be a "handle".
Last edited on
@lastchance Thanks for your answer. Can you give me clue how to use the surface triangle information to generate the mesh for internal part.
@newbieg
Thanks for your help. I'm sharing one stl file here https://www.mediafire.com/file/dy1rgj94mkdflve/AMW2011B.stl/file so you can see the stl file.
It's an interesting shape, kind of like ancient pipes with something rusting into it, or a heart and arteries. (Blender opened it just fine) Oddly the object is way away from the global center. If that is a mistake then my guess is that scaling was attempted and movement happened instead.
So... what is the goal here?
Are you just trying to output the mesh to screen, or should the goal be more for editing/modifying the object?
What is your GUI library... SDL? WindowsAPI? GTK? GLFW?
What tools are you wanting to use, like OpenGL or some other 3D Library/API?
That will affect what type of information will want to store, how to store them, as well as the types of objects and tools you might use.

What are you trying to do with the data?
What should this mesh be capable of? (Storing color, Position over time, Weight-paint, etc), or do you need the mesh to be compatible with an existing system?

Definition of a mesh: "A mesh is a collection of vertices, edges, and faces that describe the shape of a 3D object".
My problem is that the information in the STL file fully describes a version of a mesh, but there are many ways to define the mesh of an object.

My assumption so far has been that you are trying to create your own 3D editing software. Is that the case? Otherwise, what software are we trying to help you in?

Can you give me clue how to use the surface triangle information to generate the mesh for internal part.
If I understand this question and if we were using blender then import the object, scale it up a bit, then set your camera and light-source inside of the object. If the screen is blank at render time then flip the object's normals and/or increase your light strength.
Last edited on
@newbieg The goal is to construct a mesh for inside the domain, like a 3D finite difference mesh or a cubic finite element mesh.
Yes, this is an artery of the heart or it can be any other Biomedical application. I'm going to simulate the blood flow inside the arteries. Before this, I generated the mesh inside the code and then had my code working perfectly. Now for a more realistic test case, I got some stl files, but as you know the stl gives just the bounding surface information but I need to solve the blood flow inside the domain, that's why I need to construct my own mesh inside this bounded surface.
I want the mesh just to give me the coordinates.
What is your GUI library... SDL? WindowsAPI? GTK? GLFW?
What tools are you wanting to use, like OpenGL or some other 3D Library/API?

I'm not that much expert in graphic visualizer packages, but I'm using windows API.
I don't need anything special like coloring or other stuff, I just need the mesh coordinate for internal domain.
Specifically, I intend to write a code that read the stl file, then construct the mesh, then I would be able to read the data from generated mesh and work on it.
Last edited on
Collision detection is certainly possible, but I think that "boids" might work for your movement strategy with a constraint to a path on the lead object. With a little volume control on the boid swarm you can keep cells from contacting/penetrating the walls as they travel the path. In general things don't really bounce in flowing fluids, and collisions are not nearly as dramatic in a moving fluid for objects inside of the flow. {While they do spin, most of the momentum is imparted by the fluid under water because the water is constantly pushing back}. Just slow the cells down if they are furthest away from the path to simulate laminar flow.

http://usir.salford.ac.uk/id/eprint/50053/1/CMBE09-2.pdf

There is a lot of study into 3d collision detection, and a lot of tutorials that you can come across online.
https://www.euclideanspace.com/threed/animation/collisiondetect/index.htm

The minimum required information to define a plane is three points, which are provided by each triangle in the STL file; so the mesh is being fully defined by the data, it just depends on how your program interprets the data.

EDIT:
Here's something interesting in blender: https://www.youtube.com/watch?v=7mU7dNE7hKI
Last edited on
@Cplusc,
Have a look at some of the following:
- Gmsh https://gmsh.info/
- Pointwise (now called Cadence, apparently) http://www.pointwise.com/
- ICEM CFD (part of the ANSYS empire, but seems to have run out of support; there are other mesh generators in the ANSYS Workbench)
- OpenFOAM's SnappyHexMesh https://www.openfoam.com/documentation/user-guide/4-mesh-generation-and-conversion/4.4-mesh-generation-with-the-snappyhexmesh-utility

The middle two are commercial products, but if you are at a University then somebody may well have an academic licence. If you had access to it I suspect that Pointwise (or whatever it calls itself now) is closest to your needs.

What are the requirements of your volume mesh?
- structured or unstructured?
- hexahedra, tetrahedra or arbitrary polyhedra?
- how does your LBM model deal with boundary conditions? (If it allows internal ones - "immersed boundary conditions" - then you could probably just write your own cubic-cell generator and test where the STL triangles cut it.)

BTW, I loaded your STL file into StarCCM+. It loads fine, but it is well-nigh impossible to isolate the inlet and outlet boundaries because you haven't cut the main blood vessels with planes.
Last edited on
@lastchance Thanks for your help as always. I am using D3Q27 Lattice model. My interpretation of Lattice Boltzmann is it's just like finite difference method. In this model each node needs to access some information from all neighboring nodes (26 neighbors plus itself construct a D3Q27 model). The mesh should be structured.
For the curved boundary condition I'm using Flippova (https://www.sciencedirect.com/science/article/pii/S0021999199963349), Mei, Bozidi and Yu method. Immersed boundary condition is also one of my future goals but in that case I need to couple the LBM with another method which I intend to use finite element.
I didn't make these STL files, I just received them as the input information for the code. I also noticed that there are some problems at inlet but That's all I have and I'm sure there will be some issues when applying boundary condition. I believe the boundary condition will be applied on some internal nodes.

I don't use the Lattice Boltzmann Method - I'd rather use standard finite-volume CFD any day - but I don't think it is restricted to cubic lattices.

one of the advantage of LBM is that The LBM was designed from scratch to run efficiently on massively parallel architectures. also it can handle complicated boundary conditions. Now when it came to parallel architecture let me ask few more questions. As you know in finite element we use domain decomposition and we divide the domain between processors, then each subdomain construct its own vector of element and then some communications will take place between processors and then boundary condition will be applied to boundary nodes, that is a short description how we solve finite element using MPI. Now, I'm not sure whether I should make a vector of lattice first and then divide the lattices between the processors or divide the domain into subdomains and then inside each subdomain make a vector of lattice and then work on them. I believe the first one causes more computational expenses. Also, I'm thinking if I have an irregular geometry then after decomposition the work loads on my processor might not be equal and that's another issue.
Last edited on
@newbeig thanks, this is good idea
Just slow the cells down if they are furthest away from the path to simulate laminar flow.
For this case I have to use my own mesh generator code, I'm not asking for a code but could someone please tell me what would be the procedure to write a mesh generator code just with bounded region coordinate which is bounch of triangle. A finite volume cubic mesh works for me.
Last edited on
@Cplusc,
If you want a structured hexahedral mesh (your D3Q27 or local 3x3x3 lattice) then I think you are either going to have to use Pointwise to generate a multiblock structured mesh or adapt your code to deal with immersed boundary conditions so that the surface can cut your cells. You have a very complicated geometry here.
Last edited on
@lastchance
I used paraview to cut the surfaces at the inlet and outlet and then used simvascular to generate the mesh. I generated a tetrahedron mesh which is not suitable for this application. Most of the softwares just generate a triangle based type mesh, not cubic.
adapt your code to deal with immersed boundary conditions so that the surface can cut your cells.

I'm not sure if this works or not, but even if works then I just limited my problem to immersed boundary condition and I won't be able to see the affect of different type of boundary condition on flow field. I was thinking just take every two neighbor triangle on the surface, then rotate them somehow that come to on plane, then somehow I could make the cubic mesh, But every rotation can rotate all other triangles. I even can't make the algorithm on how from this triangle make a cubic mesh for the bounded area. Yes, it's a complicated geometry.
Last edited on
@lastchance
I got an idea but I'm not sure whether it would be a correct solution or not. As far as we have the surface coordinate from surface triangulation, would that be possible to recreate the mesh on the surface to quadratic element and then constructing the hexatetral mesh for internal domain would be easier.
@Cplusc,
Whilst you could obviously combine triangles into quadrilaterals, it would still not be a structured mesh and it won't help you generate a (multiblock) structured mesh inside.

If you are dead set on having a conformal multiblock structured mesh from that precise geometry then I think the only software likely to help you is Pointwise.

However, I'm guessing that that STL file is developed from one particular patient's CT scan. We all have different vasculature and it would be not unreasonable, scientifically, to approximate those blood vessels by curved cylindrical tubes of the appropriate dimensions, and the aneurysm by, say, a spheroid of roughly the right size. Then you can write your own structured grid generator to fit those approximate tubes. (Start with the basic topology and then curve it appropriately).

If you are a PhD student or PostDoc then now would be a good time to have a chat with your supervisor.
Yes, I see, it won't be structured. You're right, the stl is from one specific patient's CT scan.
Last edited on
For generating the mesh inside a complex geometry having the stl file, I start from one arbitrary point in the domain with the coordinate x0,y0 and z0. I'll consider dx=dy=dz=0.1. i,j and k are the iterators in x,y and z direction. Marching in z direction, after one iteration z=z0+k*dz. Now having the x and y coordinate of the first point (arbitrary point), I look for all those triangles that x0 and y0 of this point fall between the x and y of vertices. Now it's time to check for the z coordinate of the generated point to see if it's less than the minimum z coordinate of 3 vertices of these triangles. If yes the point will be generated and we move on to next point. The only problem I see is when the node falls between the z coordinate of 3 vertices, then I don't know if it's inside the domain or not.I believe I can generate a structured hexahedral mesh in a complex geometry using some methods like this, but still mine is not correct I think. I still feel that I'm not seeing every angle of this problem correctly and thinks still there will be some bugs. Please let me know if you have any idea.
Last edited on
I would strongly appreciate any idea on my way of generating mesh inside the complex geometry using stl files
Topic archived. No new replies allowed.