Select Git revision
view_renumbering.py
t13.f90 5.21 KiB
! ------------------------------------------------------------------------------
!
! Gmsh Fortran tutorial 13
!
! Remeshing an STL file without an underlying CAD model
!
! ------------------------------------------------------------------------------
program t13
use, intrinsic :: iso_c_binding
use gmsh
implicit none
type(gmsh_t) :: gmsh
integer(c_int) :: ret
real(c_double), parameter :: lc = .1
character(len=GMSH_API_MAX_STR_LEN) :: cmd
call gmsh%initialize()
! Create ONELAB parameters with remeshing options:
call gmsh%onelab%set('['//&
'{'//&
'"type":"number",'//&
'"name":"Parameters/Angle for surface detection",'//&
'"values":[40],'//&
'"min":20,'//&
'"max":120,'//&
'"step":1'//&
'},'//&
'{'//&
'"type":"number",'//&
'"name":"Parameters/Create surfaces guaranteed to be parametrizable",'//&
'"values":[0],'//&
'"choices":[0, 1]'//&
'},'//&
'{'//&
'"type":"number",'//&
'"name":"Parameters/Apply funny mesh size field?",'//&
'"values":[0],'//&
'"choices":[0, 1]'//&
'}'//&
']')
! Create the geometry and mesh it:
call createGeometryAndMesh()
call get_command(cmd)
if (index(cmd, "-nopopup") == 0) then
call gmsh%fltk%initialize()
do while (transfer(gmsh%fltk%isAvailable(), .true.) .and. checkForEvent())
call gmsh%fltk%wait()
end do
end if
call gmsh%finalize()
contains
subroutine createGeometryAndMesh()
real(c_double) :: curveAngle, angle, forceParametrizablePatches
real(c_double), allocatable :: tmp(:)
integer(c_int), allocatable :: s(:,:)
integer(c_int) :: l, f
logical :: includeBoundary
! Clear all models and merge an STL mesh that we would like to remesh (from
! the parent directory):
call gmsh%clear()
call gmsh%merge('../t13_data.stl')
! We first classify ("color") the surfaces by splitting the original surface
! along sharp geometrical features. This will create new discrete surfaces,
! curves and points.
! Angle between two triangles above which an edge is considered as sharp,
! retrieved from the ONELAB database (see below):
call gmsh%onelab%getNumber('Parameters/Angle for surface detection', tmp)
angle = tmp(1); deallocate(tmp)
! For complex geometries, patches can be too complex, too elongated or too
! large to be parametrized; setting the following option will force the
! creation of patches that are amenable to reparametrization:
call gmsh%onelab%getNumber(&
'Parameters/Create surfaces guaranteed to be parametrizable', tmp)
forceParametrizablePatches = tmp(1); deallocate(tmp)
! For open surfaces include the boundary edges in the classification
! process:
includeBoundary = .true.
! Force curves to be split on given angle:
curveAngle = 180
call gmsh%model%mesh%classifySurfaces(angle * M_PI / 180., includeBoundary, &
transfer(forceParametrizablePatches, .false.), &
curveAngle * M_PI / 180.)
! Create a geometry for all the discrete curves and surfaces in the mesh, by
! computing a parametrization for each one
call gmsh%model%mesh%createGeometry()
! Note that if a CAD model (e.g. as a STEP file, see `t20.f90') is available
! instead of an STL mesh, it is usually better to use that CAD model instead
! of the geometry created by reparametrizing the mesh% Indeed, CAD
! geometries will in general be more accurate, with smoother
! parametrizations, and will lead to more efficient and higher quality
! meshing. Discrete surface remeshing in Gmsh is optimized to handle dense
! STL meshes coming from e.g. imaging systems, where no CAD is available; it
! is less well suited for the poor quality STL triangulations (optimized for
! size, with e.g. very elongated triangles) that are usually generated by
! CAD tools for e.g. 3D printing.
! Create a volume from all the surfaces
call gmsh%model%getEntities(s, dim=2)
l = gmsh%model%geo%addSurfaceLoop(s(2, :))
ret = gmsh%model%geo%addVolume([l])
call gmsh%model%geo%synchronize()
! We specify element sizes imposed by a size field, just because we can :-)
f = gmsh%model%mesh%field%add("MathEval")
call gmsh%onelab%getNumber('Parameters/Apply funny mesh size field?', tmp)
if (int(tmp(1)) > 0) then
call gmsh%model%mesh%field%setString(f, "F", "2*Sin((x+y)/5) + 3")
else
call gmsh%model%mesh%field%setString(f, "F", "4")
end if
call gmsh%model%mesh%field%setAsBackgroundMesh(f)
call gmsh%model%mesh%generate(3)
call gmsh%write('t13.msh')
end subroutine createGeometryAndMesh
! Launch the GUI and handle the "check" event to recreate the geometry and mesh
! with new parameters if necessary:
logical function checkForEvent()
character(len=GMSH_API_MAX_STR_LEN), allocatable :: action(:)
checkForEvent = .false.
call gmsh%onelab%getString("ONELAB/Action", action)
if (size(action) > 0) then
if (trim(action(1)) == "check") then
call gmsh%onelab%setString("ONELAB/Action", [c_null_char])
call createGeometryAndMesh()
call gmsh%graphics%draw()
end if
end if
checkForEvent = .true.
end function checkForEvent
end program t13