stl_module Module

STL (STereoLithography) file library.

Author

  • Jacob Williams, Jan 12, 2020.

License

  • BSD-3

Reference

  • https://en.wikipedia.org/wiki/STL_(file_format)

Uses

  • module~~stl_module~~UsesGraph module~stl_module stl_module iso_c_binding iso_c_binding module~stl_module->iso_c_binding iso_fortran_env iso_fortran_env module~stl_module->iso_fortran_env

Variables

Type Visibility Attributes Name Initial
real(kind=wp), private, parameter :: zero = 0.0_wp
real(kind=wp), private, parameter :: one = 1.0_wp
real(kind=wp), private, parameter :: deg2rad = acos(-1.0_wp)/180.0_wp

degrees to radians

real(kind=wp), private, parameter, dimension(3) :: x_unit = [one, zero, zero]

x-axis unit vector

real(kind=wp), private, parameter, dimension(3) :: y_unit = [zero, one, zero]

y-axis unit vector

real(kind=wp), private, parameter, dimension(3) :: z_unit = [zero, zero, one]

z-axis unit vector


Derived Types

type, private ::  plate

a 3D triangular plate. [note that the order of the vertices defines the surface normal via the right-hand rule]

Components

Type Visibility Attributes Name Initial
real(kind=wp), public, dimension(3) :: v1 = zero

first vertex

real(kind=wp), public, dimension(3) :: v2 = zero

second vertex

real(kind=wp), public, dimension(3) :: v3 = zero

third vertex

type, public ::  stl_file

the main class for STL file I/O.

Components

Type Visibility Attributes Name Initial
integer, private :: n_plates = 0

number of plates

integer, private :: chunk_size = 1000

expand plates array in chunks of this size

type(plate), private, dimension(:), allocatable :: plates

the array of plates

Type-Bound Procedures

procedure, public :: write_ascii_stl_file
procedure, public :: write_binary_stl_file
procedure, public :: read => read_binary_stl_file
procedure, public :: read_tab_file
procedure, public :: destroy => destroy_stl_file
procedure, public :: add_plate
procedure, public :: add_sphere
procedure, public :: add_cylinder
procedure, public :: add_curve
procedure, public :: add_cone
procedure, public :: add_arrow
procedure, public :: add_axes
procedure, public :: shift_mesh
procedure, public :: set_chunk_size
procedure, private :: generate_circle
procedure, private :: compute_vertex_scale

Functions

private pure function compute_vertex_scale(me, bounding_box) result(scale)

Compute the scale factor for the vertices (for writing to a file).

Arguments

Type IntentOptional Attributes Name
class(stl_file), intent(in) :: me
real(kind=wp), intent(in), optional :: bounding_box

scale vertices so that model fits in a box of this size (if <=0, no scaling is done)

Return Value real(kind=wp)

scale factor

private pure function perpendicular(v1, v2) result(is_parallel)

Returns true if the two vectors are perpendicular.

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in), dimension(:) :: v1
real(kind=wp), intent(in), dimension(:) :: v2

Return Value logical

private pure function normal(v1, v2, v3) result(n)

Normal vector for the plate (computed using right hand rule).

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in), dimension(3) :: v1

first vertex of the triangle [x,y,z]

real(kind=wp), intent(in), dimension(3) :: v2

second vertex of the triangle [x,y,z]

real(kind=wp), intent(in), dimension(3) :: v3

third vertex of the triangle [x,y,z]

Return Value real(kind=wp), dimension(3)

surface normal vector

private pure function unit(r) result(rhat)

3x1 Unit vector.

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in), dimension(3) :: r

Return Value real(kind=wp), dimension(3)

private pure function cross(a, b) result(axb)

Vector cross product.

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in), dimension(3) :: a
real(kind=wp), intent(in), dimension(3) :: b

Return Value real(kind=wp), dimension(3)

private pure function spherical_to_cartesian(r, alpha, beta) result(rvec)

Convert spherical (r,alpha,beta) to Cartesian (x,y,z).

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: r

magnitude

real(kind=wp), intent(in) :: alpha

right ascension [deg]

real(kind=wp), intent(in) :: beta

declination [deg]

Return Value real(kind=wp), dimension(3)

[x,y,z] vector

private pure function axis_angle_rotation(v, k, theta) result(vrot)

Author
Jacob Williams
Date
7/20/2014

Rotate a 3x1 vector in space, given an axis and angle of rotation.

Read more…

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in), dimension(3) :: v

vector to rotate

real(kind=wp), intent(in), dimension(3) :: k

rotation axis

real(kind=wp), intent(in) :: theta

rotation angle [deg]

Return Value real(kind=wp), dimension(3)

result

private pure function vector_projection(a, b) result(c)

The projection of one vector onto another vector.

Read more…

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in), dimension(:) :: a

the original vector

real(kind=wp), intent(in), dimension(size(a)) :: b

the vector to project on to

Return Value real(kind=wp), dimension(size(a))

the projection of a onto b

private pure function vector_projection_on_plane(a, b) result(c)

Project a vector onto a plane.

Read more…

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in), dimension(3) :: a

the original vector

real(kind=wp), intent(in), dimension(3) :: b

the plane to project on to (a normal vector)

Return Value real(kind=wp), dimension(3)

the projection of a onto the b plane


Subroutines

private subroutine destroy_stl_file(me)

Destroy an stl_file.

Arguments

Type IntentOptional Attributes Name
class(stl_file), intent(inout) :: me

private subroutine set_chunk_size(me, chunk_size)

Set the chunk size in the class.

Arguments

Type IntentOptional Attributes Name
class(stl_file), intent(inout) :: me
integer, intent(in) :: chunk_size

must be >0

private subroutine add_plate(me, v1, v2, v3)

Add a plate to the class.

Arguments

Type IntentOptional Attributes Name
class(stl_file), intent(inout) :: me
real(kind=wp), intent(in), dimension(3) :: v1

first vertex

real(kind=wp), intent(in), dimension(3) :: v2

second vertex

real(kind=wp), intent(in), dimension(3) :: v3

third vertex

private subroutine write_binary_stl_file(me, filename, istat, bounding_box)

Generate a binary STL file.

Read more…

Arguments

Type IntentOptional Attributes Name
class(stl_file), intent(in) :: me
character(len=*), intent(in) :: filename

STL file name

integer, intent(out) :: istat

iostat code (=0 if no errors)

real(kind=wp), intent(in), optional :: bounding_box

scale vertices so that model fits in a box of this size (if <=0, no scaling is done)

private subroutine read_binary_stl_file(me, filename, istat)

Read a binary STL file.

Arguments

Type IntentOptional Attributes Name
class(stl_file), intent(out) :: me
character(len=*), intent(in) :: filename

STL file name

integer, intent(out) :: istat

iostat code (=0 if no errors)

private subroutine read_tab_file(me, filename, istat)

Read a text vertex-facet file.

Read more…

Arguments

Type IntentOptional Attributes Name
class(stl_file), intent(out) :: me
character(len=*), intent(in) :: filename

Vertex-facet file name

integer, intent(out) :: istat

iostat code (=0 if no errors)

private subroutine write_ascii_stl_file(me, filename, modelname, istat, bounding_box)

Generate an ascii STL file.

Arguments

Type IntentOptional Attributes Name
class(stl_file), intent(in) :: me
character(len=*), intent(in) :: filename

STL file name

character(len=*), intent(in) :: modelname

the solid name (should not contain spaces)

integer, intent(out) :: istat

iostat code (=0 if no errors)

real(kind=wp), intent(in), optional :: bounding_box

scale vertices so that model fits in a box of this size (if <=0, no scaling is done)

private subroutine shift_mesh(me)

Shift the vertex coordinates so that there are no non-positive components.

Arguments

Type IntentOptional Attributes Name
class(stl_file), intent(inout) :: me

private subroutine add_sphere(me, center, radius, num_lat_points, num_lon_points)

Add a sphere to an STL file.

Arguments

Type IntentOptional Attributes Name
class(stl_file), intent(inout) :: me
real(kind=wp), intent(in), dimension(3) :: center

coordinates of sphere center [x,y,z]

real(kind=wp), intent(in) :: radius

radius of the sphere

integer, intent(in) :: num_lat_points

number of latitude points (not counting poles)

integer, intent(in) :: num_lon_points

number of longitude points

private subroutine add_cylinder(me, v1, v2, radius, num_points, initial_cap, final_cap, initial_normal, final_normal, final_normal_used, initial_vector, final_initial_vector_used)

Add a cylinder to an STL file.

Read more…

Arguments

Type IntentOptional Attributes Name
class(stl_file), intent(inout) :: me
real(kind=wp), intent(in), dimension(3) :: v1

coordinates of initial point

real(kind=wp), intent(in), dimension(3) :: v2

coordinates of final point

real(kind=wp), intent(in) :: radius

radius of the cylinder

integer, intent(in) :: num_points

number of point on the circle (>=3)

logical, intent(in) :: initial_cap

add a cap plate to the initial point

logical, intent(in) :: final_cap

add a cap plate to the final point

real(kind=wp), intent(in), optional, dimension(3) :: initial_normal

outward normal vector for initial circle

real(kind=wp), intent(in), optional, dimension(3) :: final_normal

outward normal vector for final circle

real(kind=wp), intent(out), optional, dimension(3) :: final_normal_used

outward normal vector for final circle actually used

real(kind=wp), intent(in), optional, dimension(3) :: initial_vector

vector to use to generate the initial circle (x_unit by default)

real(kind=wp), intent(out), optional, dimension(3) :: final_initial_vector_used

the initial vector used for the final cap to generate the points

private subroutine add_cone(me, v1, v2, radius, num_points, initial_cap, initial_normal)

Add a cone to an STL file.

Read more…

Arguments

Type IntentOptional Attributes Name
class(stl_file), intent(inout) :: me
real(kind=wp), intent(in), dimension(3) :: v1

coordinates of initial point (bottom of the cone)

real(kind=wp), intent(in), dimension(3) :: v2

coordinates of final point (point of the cone)

real(kind=wp), intent(in) :: radius

radius of the cone (the bottom plate)

integer, intent(in) :: num_points

number of point on the circle (>=3)

logical, intent(in) :: initial_cap

add a cap plate to the initial point (bottom)

real(kind=wp), intent(in), optional, dimension(3) :: initial_normal

outward normal vector for initial plate (bottom)

private subroutine add_axes(me, origin, vx, vy, vz, radius, num_points, arrowhead_radius_factor, arrowhead_length_factor)

Add x,y,z axes to an STL file.

Arguments

Type IntentOptional Attributes Name
class(stl_file), intent(inout) :: me
real(kind=wp), intent(in), dimension(3) :: origin

coordinates of the origin of the axes

real(kind=wp), intent(in), dimension(3) :: vx

x axis vector

real(kind=wp), intent(in), dimension(3) :: vy

y axis vector

real(kind=wp), intent(in), dimension(3) :: vz

z axis vector

real(kind=wp), intent(in) :: radius

radius of the cylinder

integer, intent(in) :: num_points

number of point on the circle (>=3)

real(kind=wp), intent(in) :: arrowhead_radius_factor

arrowhead cone radius factor (multiple of cylinder radius)

real(kind=wp), intent(in) :: arrowhead_length_factor

arrowhead tip length factor (multiple of vector length)

private subroutine add_arrow(me, origin, v, radius, num_points, arrowhead_radius_factor, arrowhead_length_factor)

Add an arrow to an STL file.

Arguments

Type IntentOptional Attributes Name
class(stl_file), intent(inout) :: me
real(kind=wp), intent(in), dimension(3) :: origin

coordinates of the origin of the axes

real(kind=wp), intent(in), dimension(3) :: v

vector

real(kind=wp), intent(in) :: radius

radius of the cylinder

integer, intent(in) :: num_points

number of point on the circle (>=3)

real(kind=wp), intent(in) :: arrowhead_radius_factor

arrowhead cone radius factor (multiple of cylinder radius)

real(kind=wp), intent(in) :: arrowhead_length_factor

arrowhead tip length factor (multiple of vector length)

private subroutine generate_circle(me, c, radius, n, nc, add_circle, circle, initial_vector, cw)

Generate the points in a circle, and optionally add it as a plate.

Arguments

Type IntentOptional Attributes Name
class(stl_file), intent(inout) :: me
real(kind=wp), intent(in), dimension(3) :: c

center of the circle

real(kind=wp), intent(in) :: radius

radius of the cylinder

real(kind=wp), intent(in), dimension(3) :: n

normal vector to the circle

integer, intent(in) :: nc

number of points on the circle (must be at least 3)

logical, intent(in) :: add_circle

to also add to the circle as a plate

real(kind=wp), intent(out), dimension(:,:), allocatable :: circle

points on the circle

real(kind=wp), intent(in), optional, dimension(3) :: initial_vector

vector to use to generate the initial circle (x_unit by default)

logical, intent(in), optional :: cw

generate the points in the clockwise direction abound n (default is false)

private subroutine add_curve(me, x, y, z, radius, num_points, initial_cap, initial_normal, final_cap, final_normal, initial_vector)

Add a curve to an STL file.

Read more…

Arguments

Type IntentOptional Attributes Name
class(stl_file), intent(inout) :: me
real(kind=wp), intent(in), dimension(:) :: x

x coordinate array

real(kind=wp), intent(in), dimension(:) :: y

y coordinate array

real(kind=wp), intent(in), dimension(:) :: z

z coordinate array

real(kind=wp), intent(in) :: radius

radius of the cylinder

integer, intent(in) :: num_points

number of point on the cylinder perimeter

logical, intent(in), optional :: initial_cap

add a cap plate to the initial point

real(kind=wp), intent(in), optional, dimension(3) :: initial_normal

outward normal vector for initial circle

logical, intent(in), optional :: final_cap

add a cap plate to the final point

real(kind=wp), intent(in), optional, dimension(3) :: final_normal

outward normal vector for final circle

real(kind=wp), intent(in), optional, dimension(3) :: initial_vector

vector to use to generate the first circle (x_unit by default)