Skip to content

Commit 6c86b6d

Browse files
committed
Add generate_stl method with doc
1 parent 5cb953f commit 6c86b6d

File tree

1 file changed

+98
-0
lines changed

1 file changed

+98
-0
lines changed

bladex/blade.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,104 @@ def generate_iges(self,
796796
display.DisplayShape(generated_tip, update=True)
797797
start_display()
798798

799+
def generate_stl(self, min_length=None, max_length=None, outfile_stl=None):
800+
"""
801+
Generate and export the .STL surface mesh for the blade as a whole,
802+
including the upper face, lower face and tip. The method utilizes
803+
modules from OCC SMESH which is standalone mesh framework based on
804+
SALOME mesher project. Please refer to https://github.com/tpaviot
805+
and http://docs.salome-platform.org/7/gui/SMESH/index.html for
806+
further details.
807+
808+
This method requires PythonOCC and SMESH to be installed.
809+
810+
:param double min_length: smallest distance between two nodes. Default
811+
value is None
812+
:param double max_length: largest distance between two nodes. Default
813+
value is None
814+
:param string outfile_stl: if string is passed then the method exports
815+
the generated 2D surface mesh into .stl file holding the name
816+
<outfile_stl>.stl. Default value is None
817+
818+
We note that since the current implementation performs triangulation
819+
based on a topological compound that combines the blade 3 generated
820+
shapes without "fusion", it may happen that the generated triangulation
821+
of the upper and lower blade faces do not share the same exact nodes
822+
on the joint edge/wire resulting from the faces intersection. The
823+
current implementation can be enough for visualization purpose. However
824+
if the generated mesh is intended for computational analysis then a
825+
manual mesh healing is recommended by the user (e.g. see
826+
"Repair > Sewing" in SALOME GUI) for a proper mesh closure.
827+
"""
828+
from OCC.SMESH import SMESH_Gen, SMESH_MeshVSLink
829+
from OCC.StdMeshers import (StdMeshers_Arithmetic1D, StdMeshers_TrianglePreference,
830+
StdMeshers_Regular_1D, StdMeshers_Quadrangle_2D,
831+
StdMeshers_MEFISTO_2D)
832+
from OCC.BRep import BRep_Builder
833+
from OCC.TopoDS import TopoDS_Shape, TopoDS_Compound
834+
835+
# First we check that blade shapes are generated, otherwise we generate
836+
# them. After that we combine the generated_upper_face,
837+
# generated_lower_face, and generated_tip into a topological compound
838+
# that we use to compute the surface mesh
839+
if (self.generated_upper_face is None) or not isinstance(self.generated_upper_face, TopoDS_Shape):
840+
# Upper face is generated with a maximal U degree = 1
841+
self._generate_upper_face(maxDeg=1)
842+
if (self.generated_lower_face is None) or not isinstance(self.generated_lower_face, TopoDS_Shape):
843+
# Upper face is generated with a maximal U degree = 1
844+
self._generate_lower_face(maxDeg=1)
845+
if (self.generated_tip is None) or not isinstance(self.generated_tip, TopoDS_Shape):
846+
# Upper face is generated with a maximal U degree = 1
847+
self._generate_tip(maxDeg=1)
848+
849+
# Now we regroup all the shapes into a TopoDS_Compound
850+
aCompound = TopoDS_Compound()
851+
aBuilder = BRep_Builder()
852+
aBuilder.MakeCompound(aCompound)
853+
# Add shapes
854+
aBuilder.Add(aCompound,self.generated_upper_face)
855+
aBuilder.Add(aCompound,self.generated_lower_face)
856+
aBuilder.Add(aCompound,self.generated_tip)
857+
858+
# In the following we build the surface mesh according to the given
859+
# hypotheses
860+
aMeshGen = SMESH_Gen()
861+
aMesh = aMeshGen.CreateMesh(0, True)
862+
# Adding 1D hypothesis and algorithms
863+
# Wire discretization. Nodes are distributed based on Arithmetic1D
864+
# hypothesis which allows to split edges into segments with a length
865+
# that changes in arithmetic progression (Lk = Lk-1 + d) beginning
866+
# from a given min length and up to a given max length. More about
867+
# 1D hypotheses can be viewed through:
868+
# http://docs.salome-platform.org/7/gui/SMESH/a1d_meshing_hypo_page.html
869+
an1DHypothesis = StdMeshers_Arithmetic1D(0, 0, aMeshGen)
870+
# Smallest distance between 2 points
871+
an1DHypothesis.SetLength(min_length, False)
872+
# Longest distance between 2 points
873+
an1DHypothesis.SetLength(max_length, True)
874+
# Regular Interpolation
875+
an1DAlgo = StdMeshers_Regular_1D(1, 0, aMeshGen)
876+
# Adding 2D hypothesis and algorithms
877+
# 2D surface mesh -- Triangulations
878+
a2dHypothseis = StdMeshers_TrianglePreference(2, 0, aMeshGen)
879+
a2dAlgo = StdMeshers_MEFISTO_2D(3, 0, aMeshGen)
880+
881+
#Calculate mesh for the topological compound containing the 3 shapes
882+
aMesh.ShapeToMesh(aCompound)
883+
884+
#Assign hyptothesis to mesh
885+
aMesh.AddHypothesis(aCompound, 0)
886+
aMesh.AddHypothesis(aCompound, 1)
887+
aMesh.AddHypothesis(aCompound, 2)
888+
aMesh.AddHypothesis(aCompound, 3)
889+
890+
#Compute the data
891+
aMeshGen.Compute(aMesh, aMesh.GetShapeToMesh())
892+
893+
if outfile_stl is not None:
894+
assert isinstance(outfile_stl, str), "outfile_stl must be a valid string."
895+
aMesh.ExportSTL(outfile_stl+'.stl', False)
896+
799897
@staticmethod
800898
def _check_string(filename):
801899
"""

0 commit comments

Comments
 (0)