|
[Sponsors] |
[CAD formats] Creating waterproof STL using snappyHexMesh or salome |
![]() |
|
LinkBack | Thread Tools | Search this Thread | Display Modes |
![]() |
![]() |
#1 |
Super Moderator
Tobias Holzmann
Join Date: Oct 2010
Location: Bad Wörishofen
Posts: 2,711
Blog Entries: 6
Rep Power: 51 ![]() ![]() ![]() |
Dear all,
the last few years I experienced the necessity of a good surface triangulation while using snappyHexMesh. Most people are using common CAD software packages and export single surfaces as STL files. These STL files have two big problems, if they represent a closed volume:
Both (and especially the second one) influences the mesh generation in a very bad way. The good thing is that in some case it does not matter ![]()
Not water proofed STL have a further bad behavior in the point of feature edges. STL's (or region STL) that share share a curvatured edge will end up with two feature edges due to the fact that the STL's share not the same points (and therefore not the same edge). After creating the feature edges, you will extract both feature edges. Now ask yourself, which line should be used? (Here one comment, please check your featureEdge mesh using paraview and correct it if its wrong with blender).
Code:
surfaceMeshTriangulate myNewSurface.stl triangulation.jpg The procedure is as follow (short form summarized and clear):
My personal suggestions are:
If you have to mesh a lot of different designs, I would prefer the generation of the STL using snappyHexMesh. You also can implement this way into a optimization loop. So good luck and keep foaming, hope this will help somebody.
__________________
Keep foaming, Tobias Holzmann Last edited by Tobi; May 1, 2016 at 16:46. |
|
![]() |
![]() |
![]() |
![]() |
#2 |
Senior Member
Derek Mitchell
Join Date: Mar 2014
Location: UK, Reading
Posts: 172
Rep Power: 13 ![]() |
So far freecad 0.16 seems to generate "waterproof " stl
__________________
A CHEERING BAND OF FRIENDLY ELVES CARRY THE CONQUERING ADVENTURER OFF INTO THE SUNSET |
|
![]() |
![]() |
![]() |
![]() |
#3 |
Member
Vignesh
Join Date: Oct 2012
Location: Darmstadt, Germany
Posts: 66
Rep Power: 13 ![]() |
Hi Tobi,
Can you tell me how to create a closed stl file when we combine individual surfaces (stl file) manually after labeling them ? I always get "surface is not closed" when i do a surface check for the combined stl file but it does not happen for the stl file of the part. Can you tell me what i am doing wrong ?? I have attached the files PS: I used salome for creating the solid which i exploded into individual surfaces.
__________________
Thanks and Regards Vignesh |
|
![]() |
![]() |
![]() |
![]() |
#4 |
Super Moderator
Tobias Holzmann
Join Date: Oct 2010
Location: Bad Wörishofen
Posts: 2,711
Blog Entries: 6
Rep Power: 51 ![]() ![]() ![]() |
Dear Vignesh,
if you have several surfaces in Salome you are not allowed to export these surfaces in the geometry module. You have to mesh the surfaces in the mesh module to make a homogeneous discretization on the lines. If you export these STL files then you end up with a waterproofed STL. That is the way I prefer for all STL's. To check it, just load your exported STL into paraview. You will see that the contact lines will not share the same triangle points.
__________________
Keep foaming, Tobias Holzmann |
|
![]() |
![]() |
![]() |
![]() |
#5 | |
Member
Vignesh
Join Date: Oct 2012
Location: Darmstadt, Germany
Posts: 66
Rep Power: 13 ![]() |
Quote:
Thanks for the quick reply. I tried as you suggested, still i get "surfaces is not closed" ![]()
__________________
Thanks and Regards Vignesh |
||
![]() |
![]() |
![]() |
![]() |
#6 |
Super Moderator
Tobias Holzmann
Join Date: Oct 2010
Location: Bad Wörishofen
Posts: 2,711
Blog Entries: 6
Rep Power: 51 ![]() ![]() ![]() |
Hi,
if you check our STL it is not closed. Each surface has different points on the interface. The interface does not share the points of both surfaces. See the picture (for you it should be obvious). Check out my STL's in my tutorials and you see that the interface (the line that is shared by both) has the same points on both surfaces.
__________________
Keep foaming, Tobias Holzmann |
|
![]() |
![]() |
![]() |
![]() |
#7 |
Member
Vignesh
Join Date: Oct 2012
Location: Darmstadt, Germany
Posts: 66
Rep Power: 13 ![]() |
Hi Tobi,
I understood the mistake that i made during meshing in salome. Thanks for pointing it out. Now its working ![]()
__________________
Thanks and Regards Vignesh |
|
![]() |
![]() |
![]() |
![]() |
#8 |
Member
Sebastian Trunk
Join Date: Mar 2015
Location: Erlangen, Germany
Posts: 60
Rep Power: 11 ![]() |
Hey Tobias,
I tried to reproduce your workflow: -stl generation in salome -created groups -created edges of the groups -change to mesh mode -triangulated the geometry by meshing -made mesh groups of the patches BUT... when I combine the patches in in big file, I still get unconnected surfaces... What point do I miss? I want the stl file as input for cfMesh! Thanks a lot for your advice! Best regards, Sebastian At this point, I |
|
![]() |
![]() |
![]() |
![]() |
#9 |
Member
Vignesh
Join Date: Oct 2012
Location: Darmstadt, Germany
Posts: 66
Rep Power: 13 ![]() |
Hi Sebastian,
Did you keep the edge length same for all faces (groups) while meshing ?
__________________
Thanks and Regards Vignesh |
|
![]() |
![]() |
![]() |
![]() |
#10 |
Member
Sebastian Trunk
Join Date: Mar 2015
Location: Erlangen, Germany
Posts: 60
Rep Power: 11 ![]() |
Hey Vignesh,
Jap, I did not change any settings for the meshing! How is your workflo9w? Which geometry parts do you use? I am not sure if I have to use the whole geometry to mesh (how do i capture feature edges) or if a mesh the grouped geometry parts on their own with the same settings? Just from viewing the stl in paraview, it was fine. The triangles in the areas where the patches touch each looked quite nice... Thanks again... Best regards, Sebastian |
|
![]() |
![]() |
![]() |
![]() |
#11 | |
Member
Vignesh
Join Date: Oct 2012
Location: Darmstadt, Germany
Posts: 66
Rep Power: 13 ![]() |
Hi Sebastian,
My workflow in salome is
Hope this helps you Quote:
__________________
Thanks and Regards Vignesh |
||
![]() |
![]() |
![]() |
![]() |
#12 |
Member
Sebastian Trunk
Join Date: Mar 2015
Location: Erlangen, Germany
Posts: 60
Rep Power: 11 ![]() |
Thanks a lot for your fast replay!
I will give it a try on my geometry and report the result... |
|
![]() |
![]() |
![]() |
![]() |
#13 |
Member
Sebastian Trunk
Join Date: Mar 2015
Location: Erlangen, Germany
Posts: 60
Rep Power: 11 ![]() |
All good (for the moment
![]() Thank you so much! |
|
![]() |
![]() |
![]() |
![]() |
#14 |
New Member
Thazin
Join Date: Mar 2016
Posts: 8
Rep Power: 10 ![]() |
Hi vigneshTG,
I'm using meshLab to convert text file to stl format. After that, I've used surfaceCheck to check my geometry. End of surfaceCheck, surface is not closed errors are shown no matter how I try to fix with admesh or meshLab. How should I fix that problem? Please advice me!! thanks |
|
![]() |
![]() |
![]() |
![]() |
#16 |
New Member
Thazin
Join Date: Mar 2016
Posts: 8
Rep Power: 10 ![]() |
Dear Tobi,
Thanks for your reply and suggest. Can I use salome even my terrain is topography? |
|
![]() |
![]() |
![]() |
![]() |
#17 |
Member
Utkan Caliskan
Join Date: Aug 2014
Posts: 42
Rep Power: 12 ![]() |
Dear Tobi,
I was having problems for days and now that actually hits the spot. I will try Salome right quick, thanks. Utkan |
|
![]() |
![]() |
![]() |
![]() |
#18 |
Senior Member
Derek Mitchell
Join Date: Mar 2014
Location: UK, Reading
Posts: 172
Rep Power: 13 ![]() |
The salome user interface is a little clunky, and for anything complex or repetitive you will need the script interface. This script interface can also help in understanding the work flow needed. In the attached salome python script I have created the stl files and UNV file for the snappyhexmesh tutorial for Chtmultiregion.
In this script you can see:
Code:
# -*- coding: utf-8 -*- ### ### This file is salome script that shows how to create meshs sutiable for openFOAM # it uses the geometry from # run/tutorials/heatTransfer/chtMultiRegionSimpleFoam/multiRegionHeaterRadiation # then use in # run/tutorials/mesh/snappyHexMesh/snappyMultiRegionHeater # ####### import sys import salome salome.salome_init() theStudy = salome.myStudy import salome_notebook notebook = salome_notebook.NoteBook(theStudy) sys.path.insert( 0, r'/home/derekm/salwork') ### ### GEOM component ### import GEOM from salome.geom import geomBuilder import math import SALOMEDS geompy = geomBuilder.New(theStudy) O = geompy.MakeVertex(0, 0, 0) OX = geompy.MakeVectorDXDYDZ(1, 0, 0) OY = geompy.MakeVectorDXDYDZ(0, 1, 0) OZ = geompy.MakeVectorDXDYDZ(0, 0, 1) ####### # create tutorial geometry from vertexes as in tutorial ####### heater_b1_p1_ = geompy.MakeVertex(-0.01, 0, -0.05) heater_b1_p2_ = geompy.MakeVertex(0.01, 0.01, 0.05) heater_b2_p1_ = geompy.MakeVertex(-0.01, -0.04, -0.01) heater_b2_p2_ = geompy.MakeVertex(0.01, 0.01, 0.01) heater_b1 = geompy.MakeBoxTwoPnt(heater_b1_p1_, heater_b1_p2_) heater_b2 = geompy.MakeBoxTwoPnt(heater_b2_p1_, heater_b2_p2_) left_p1_ = geompy.MakeVertex(-0.1, 0, -0.05) left_p2_ = geompy.MakeVertex(-0.01, 0.01, 0.05) left_c = geompy.MakeBoxTwoPnt(left_p1_, left_p2_) right_p1 = geompy.MakeVertex(0.01, 0, -0.05) right_p2 = geompy.MakeVertex(0.1, 0.01, 0.05) right_c = geompy.MakeBoxTwoPnt(right_p1, right_p2) top_p1 = geompy.MakeVertex(-0.1, 0.01, -0.05) top_p2_ = geompy.MakeVertex(0.1, 0.04, 0.05) top_c = geompy.MakeBoxTwoPnt(top_p1, top_p2_) all_p1_ = geompy.MakeVertex(-0.1, -0.04, -0.05) all_p2 = geompy.MakeVertex(0.1, 0.04, 0.05) all = geompy.MakeBoxTwoPnt(all_p1_, all_p2) [minXall,minYall,minZall,maxZall,maxYall,maxXall] = geompy.ExtractShapes(all, geompy.ShapeType["FACE"], True) bottom_c = geompy.MakeCutList(all, [heater_b1, heater_b2, left_c, right_c, top_c], True) heater_c = geompy.MakeFuseList([heater_b1, heater_b2], True, True) ## geompy.addToStudy( O, 'O' ) geompy.addToStudy( OX, 'OX' ) geompy.addToStudy( OY, 'OY' ) geompy.addToStudy( OZ, 'OZ' ) geompy.addToStudy( heater_b1_p1_, 'heater_b1_p1' ) geompy.addToStudy( heater_b1_p2_, 'heater_b1_p2' ) geompy.addToStudy( heater_b2_p1_, 'heater_b2_p1' ) geompy.addToStudy( heater_b2_p2_, 'heater_b2_p2' ) geompy.addToStudy( heater_b1, 'heater_b1' ) geompy.addToStudy( heater_b2, 'heater_b2' ) geompy.addToStudy( left_p1_, 'left_p1' ) geompy.addToStudy( left_p2_, 'left_p2' ) geompy.addToStudy( left_c, 'left_c' ) geompy.addToStudy( right_p1, 'right_p1' ) geompy.addToStudy( top_p1, 'top_p1' ) geompy.addToStudy( right_p2, 'right_p2' ) geompy.addToStudy( right_c, 'right_c' ) geompy.addToStudy( top_p2_, 'top_p2' ) geompy.addToStudy( top_c, 'top_c' ) geompy.addToStudy( all_p1_, 'all_p1') geompy.addToStudy( all_p2, 'all_p2' ) geompy.addToStudy( all, 'all' ) geompy.addToStudy( bottom_c, 'bottom_c' ) geompy.addToStudy( heater_c, 'heater_c' ) ############## # build region groups ############## # build partition object Partition_1 = geompy.MakePartition([all], [left_c, right_c, top_c, bottom_c, heater_c], [], [], geompy.ShapeType["SOLID"], 0, [], 0) ####### geompy.addToStudy( Partition_1, 'Partition_1' ) ### collect face ids for each region using the region shape top_cfaces = geompy.GetShapesOnShapeIDs(top_c, Partition_1, geompy.ShapeType["FACE"], GEOM.ST_ONIN) right_cfaces = geompy.GetShapesOnShapeIDs(right_c, Partition_1, geompy.ShapeType["FACE"], GEOM.ST_ONIN) left_cfaces = geompy.GetShapesOnShapeIDs(left_c, Partition_1, geompy.ShapeType["FACE"], GEOM.ST_ONIN) heater_cfaces = geompy.GetShapesOnShapeIDs(heater_c, Partition_1, geompy.ShapeType["FACE"], GEOM.ST_ONIN) bottom_cfaces = geompy.GetShapesOnShapeIDs(bottom_c, Partition_1, geompy.ShapeType["FACE"], GEOM.ST_ONIN) ### create groups for each region top = geompy.CreateGroup(Partition_1, geompy.ShapeType["FACE"]) geompy.UnionIDs(top, top_cfaces) geompy.addToStudyInFather(Partition_1, top, "top") right = geompy.CreateGroup(Partition_1, geompy.ShapeType["FACE"]) geompy.UnionIDs(right, right_cfaces) geompy.addToStudyInFather(Partition_1, right, "right") left = geompy.CreateGroup(Partition_1, geompy.ShapeType["FACE"]) geompy.UnionIDs(left, left_cfaces) geompy.addToStudyInFather(Partition_1, left, "left") heater = geompy.CreateGroup(Partition_1, geompy.ShapeType["FACE"]) geompy.UnionIDs(heater, heater_cfaces) geompy.addToStudyInFather(Partition_1, heater, "heater") bottom = geompy.CreateGroup(Partition_1, geompy.ShapeType["FACE"]) geompy.UnionIDs(bottom, bottom_cfaces) geompy.addToStudyInFather(Partition_1,bottom, "bottom") ########################### #patches and wall groups ########################### #use planes to collect patch and wall faces from the bounding object minX_ids= geompy.GetShapesOnPlaneWithLocationIDs ( all,geompy.ShapeType["FACE"],OX,all_p1_,GEOM.ST_ON) minY_ids= geompy.GetShapesOnPlaneWithLocationIDs ( all,geompy.ShapeType["FACE"],OY,all_p1_,GEOM.ST_ON) minZ_ids= geompy.GetShapesOnPlaneWithLocationIDs ( all,geompy.ShapeType["FACE"],OZ,all_p1_,GEOM.ST_ON) maxX_ids= geompy.GetShapesOnPlaneWithLocationIDs ( all,geompy.ShapeType["FACE"],OX,all_p2,GEOM.ST_ON) maxY_ids= geompy.GetShapesOnPlaneWithLocationIDs ( all,geompy.ShapeType["FACE"],OY,all_p2,GEOM.ST_ON) maxZ_ids= geompy.GetShapesOnPlaneWithLocationIDs ( all,geompy.ShapeType["FACE"],OZ,all_p2,GEOM.ST_ON) # create groups minX = geompy.CreateGroup(all, geompy.ShapeType["FACE"]) minY = geompy.CreateGroup(all, geompy.ShapeType["FACE"]) minX = geompy.CreateGroup(all, geompy.ShapeType["FACE"]) minZ = geompy.CreateGroup(all, geompy.ShapeType["FACE"]) maxX = geompy.CreateGroup(all, geompy.ShapeType["FACE"]) maxY = geompy.CreateGroup(all, geompy.ShapeType["FACE"]) maxZ = geompy.CreateGroup(all, geompy.ShapeType["FACE"]) geompy.UnionIDs(minX, minX_ids) geompy.UnionIDs(minY, minY_ids) geompy.UnionIDs(minZ, minZ_ids) geompy.UnionIDs(maxX, maxX_ids) geompy.UnionIDs(maxY, maxY_ids) geompy.UnionIDs(maxZ, maxZ_ids) geompy.addToStudyInFather(all,minX, "minX") geompy.addToStudyInFather(all,minY, "minY") geompy.addToStudyInFather(all,minZ, "minZ") geompy.addToStudyInFather(all,maxX, "maxX") geompy.addToStudyInFather(all,maxY, "maxY") geompy.addToStudyInFather(all,maxZ, "maxZ") ### # # meshing # ## import SMESH, SALOMEDS from salome.smesh import smeshBuilder ### # basemesh often created in blockmesh here we get salome to do it and create the patches # ### smesh = smeshBuilder.New(theStudy) all_Mesh = smesh.Mesh(all) Regular_1D = all_Mesh.Segment() Local_Length_1 = Regular_1D.LocalLength(0.01,None,1e-07) Quadrangle_2D = all_Mesh.Quadrangle(algo=smeshBuilder.QUADRANGLE) Hexa_3D = all_Mesh.Hexahedron(algo=smeshBuilder.Hexa) Local_Length_1.SetLength( 0.01 ) Local_Length_1.SetPrecision( 1e-07 ) isDone = all_Mesh.Compute() # patches and walls minX_1 = all_Mesh.GroupOnGeom(minX,'minX',SMESH.FACE) minY_1 = all_Mesh.GroupOnGeom(minY,'minY',SMESH.FACE) minZ_1 = all_Mesh.GroupOnGeom(minZ,'minZ',SMESH.FACE) maxX_1 = all_Mesh.GroupOnGeom(maxX,'maxX',SMESH.FACE) maxY_1 = all_Mesh.GroupOnGeom(maxY,'maxY',SMESH.FACE) maxZ_1 = all_Mesh.GroupOnGeom(maxZ,'maxZ',SMESH.FACE) try: all_Mesh.ExportUNV( r'/home/derekm/salwork/tmp/all_Mesh.unv' ) except: print 'ExportUNV() failed. Invalid file name?' # # region meshes # Local_Length_2 = smesh.CreateHypothesis('LocalLength') Regular_1D_1 = smesh.CreateHypothesis( "Regular_1D" ) MEFISTO_2D = smesh.CreateHypothesis('MEFISTO_2D') Local_Length_2.SetLength( 0.005 ) Local_Length_2.SetPrecision( 1e-07 ) # topAir topAir = smesh.Mesh(top) status = topAir.AddHypothesis(Local_Length_2) Regular_1D_2 = topAir.Segment() status = topAir.AddHypothesis(MEFISTO_2D) isDone = topAir.Compute() topAir.SetName( 'topAir' ) try: topAir.ExportSTL( r'/home/derekm/salwork/tmp/topAir.stl', 1 ) except: print 'ExportSTL() failed. Invalid file name?' #LeftSolid leftSolid = smesh.Mesh(left) status = leftSolid.AddHypothesis(Local_Length_2) Regular_1D_2 = leftSolid.Segment() status = leftSolid.AddHypothesis(MEFISTO_2D) isDone = leftSolid.Compute() leftSolid.SetName( 'leftSolid' ) try: leftSolid.ExportSTL( r'/home/derekm/salwork/tmp/leftSolid.stl', 1 ) except: print 'ExportSTL() failed. Invalid file name?' #rightSolid rightSolid = smesh.Mesh(right) status = rightSolid.AddHypothesis(Local_Length_2) Regular_1D_2 = rightSolid.Segment() status = rightSolid.AddHypothesis(MEFISTO_2D) isDone = rightSolid.Compute() rightSolid.SetName( 'rightSolid' ) try: rightSolid.ExportSTL( r'/home/derekm/salwork/tmp/rightSolid.stl', 1 ) except: print 'ExportSTL() failed. Invalid file name?' #heater heater_1 = smesh.Mesh(heater) status = heater_1.AddHypothesis(Local_Length_2) Regular_1D_2 = heater_1.Segment() status =heater_1.AddHypothesis(MEFISTO_2D) isDone = heater_1.Compute() heater_1.SetName( 'heater' ) try: heater_1.ExportSTL( r'/home/derekm/salwork/tmp/heater.stl', 1 ) except: print 'ExportSTL() failed. Invalid file name?' #bottomAir bottomAir = smesh.Mesh(bottom) status = bottomAir.AddHypothesis(Local_Length_2) Regular_1D_2 = bottomAir.Segment() status =bottomAir.AddHypothesis(MEFISTO_2D) isDone = bottomAir.Compute() bottomAir.SetName( 'bottomAir' ) try: bottomAir.ExportSTL( r'/home/derekm/salwork/tmp/bottomAir.stl', 1 ) except: print 'ExportSTL() failed. Invalid file name?' if salome.sg.hasDesktop(): salome.sg.updateObjBrowser(1)
__________________
A CHEERING BAND OF FRIENDLY ELVES CARRY THE CONQUERING ADVENTURER OFF INTO THE SUNSET |
|
![]() |
![]() |
![]() |
![]() |
#19 |
Super Moderator
Tobias Holzmann
Join Date: Oct 2010
Location: Bad Wörishofen
Posts: 2,711
Blog Entries: 6
Rep Power: 51 ![]() ![]() ![]() |
I do not agree with your statement. I am using Salomes GUI for really high complex geometries and till now I could do anything without the python interface. Of course you can get a lot of information out of the python script and it allows to use it for optimization but the necessity of python for complex geometry - no, I cannot agree.
Sent from my HTC One mini using CFD Online Forum mobile app
__________________
Keep foaming, Tobias Holzmann |
|
![]() |
![]() |
![]() |
![]() |
#20 | |
Senior Member
Derek Mitchell
Join Date: Mar 2014
Location: UK, Reading
Posts: 172
Rep Power: 13 ![]() |
Quote:
__________________
A CHEERING BAND OF FRIENDLY ELVES CARRY THE CONQUERING ADVENTURER OFF INTO THE SUNSET |
||
![]() |
![]() |
![]() |
|
|
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
[snappyHexMesh] Creating STL files with regions for snappyHexMesh | nusivares | OpenFOAM Meshing & Mesh Conversion | 4 | August 7, 2018 20:09 |
[snappyHexMesh] With FreeCAD: creating waterproof STL files? | robob | OpenFOAM Meshing & Mesh Conversion | 11 | April 29, 2018 11:33 |
[snappyHexMesh] Creating stl file for snappyHexMesh from xyz coordinates | Vignesh2508 | OpenFOAM Meshing & Mesh Conversion | 2 | April 25, 2017 08:43 |
[snappyHexMesh] What types of stl files are needed in snappyhexmesh? | phandy | OpenFOAM Meshing & Mesh Conversion | 1 | February 19, 2015 05:36 |
[snappyHexMesh] Experimentally obtained STL file for internal Flow SnappyHexMesh | Irish09 | OpenFOAM Meshing & Mesh Conversion | 9 | April 7, 2012 08:50 |