├── .gitignore
├── CMakeLists.txt
├── LICENSE.md
├── README.md
├── TODO.md
├── doc
└── images
│ ├── TMeshExample.png
│ ├── bdrySizeFun.png
│ ├── exampleMesh.png
│ ├── performance.png
│ ├── qtree.png
│ ├── qtree_gray.png
│ └── tMesh.png
├── share
├── cmake
│ ├── compiler_flags.cmake
│ └── directories.cmake
├── files
│ ├── comment_test.para
│ ├── example.para
│ ├── simple.para
│ ├── size_function.para
│ └── square.para
└── python
│ ├── performance.py
│ ├── plot_boundary.py
│ ├── plot_mesh.py
│ ├── plot_qtree.py
│ └── spiral.py
└── src
└── tmesh
├── CMakeLists.txt
├── include
└── tmesh
│ ├── bstrlib.h
│ ├── dbg.h
│ ├── minunit.h
│ ├── tinyexpr.h
│ ├── tmBdry.h
│ ├── tmEdge.h
│ ├── tmFront.h
│ ├── tmList.h
│ ├── tmMesh.h
│ ├── tmNode.h
│ ├── tmParam.h
│ ├── tmQtree.h
│ ├── tmTri.h
│ └── tmTypedefs.h
├── src
├── bstrlib.c
├── main.c
├── tinyexpr.c
├── tmBdry.c
├── tmEdge.c
├── tmFront.c
├── tmList.c
├── tmMesh.c
├── tmNode.c
├── tmParam.c
├── tmQtree.c
└── tmTri.c
└── test
├── geom_tests.c
├── geom_tests.h
├── tmList_tests.c
├── tmList_tests.h
├── tmParam_tests.c
├── tmParam_tests.h
├── tmesh_cylinder.c
├── tmesh_cylinder.h
├── tmesh_examples.c
├── tmesh_examples.h
├── tmesh_tests.c
├── tmesh_tests.h
└── unit_tests.c
/.gitignore:
--------------------------------------------------------------------------------
1 | build/*
2 | bin/*
3 | lib/*
4 | *.o
5 | *.dat
6 | share/python/pics/*.png
7 | src/tags
8 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | ##############################################################
2 | # LEARN C THE HARD WAY #
3 | ##############################################################
4 | # prerequisites
5 | cmake_minimum_required( VERSION 3.5.2 )
6 | project( Triangular-Mesh-Generator )
7 |
8 | # enable testing support
9 | enable_testing()
10 |
11 | # Include cmake files
12 | include( "${CMAKE_SOURCE_DIR}/share/cmake/directories.cmake" )
13 | include( "${CMAKE_SOURCE_DIR}/share/cmake/compiler_flags.cmake" )
14 |
15 | #-------------------------------------------------------------
16 | # Define modules
17 | #-------------------------------------------------------------
18 | add_subdirectory( ${SRC}/tmesh )
19 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Florian Setzwein
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # TMesh
2 | -----------------------------
3 |
4 |
5 |
6 | **TMesh** is a small program to create two-dimensional triangular grids, which can
7 | be used for Finite Element Methods or Computational Fluid Dynamics applications.
8 | The triangles are generated with an advancing-front method, for which the user must only provide edge segments that define the boundaries of the domain. Furthermore it is possible to refine
9 | triangles locally with a user-defined size function.
10 |
11 | ## Installation
12 | **TMesh** is just base on the static library **libtmesh.a**, generated in the *lib*-directory of this repository.
13 | It is automatically created upon compilation with cmake.
14 | For installation, just create a build directory and run
15 | ```sh
16 | cmake ..
17 | make install
18 | ```
19 |
20 | ## Usage of TMesh
21 | **TMesh** takes a parameter-file as input for the mesh generation. Sample files are given in *share/files/*.
22 | Basically, one only needs to define a few global parameters and the mesh boundaries in terms
23 | of boundary nodes and edges.
24 | There is the possibility to assign markers to the boundaries and to each boundary-edge.
25 | The only purpose of these markers is to identify these boundaries/edges later when the meshing is generated.
26 | Here is a simple example to create a mesh using **TMesh**:
27 | It is even possible to provide simple size function expressions through the input file.
28 | ```sh
29 | #-----------------------------------------------------------
30 | # TMESH
31 | #-----------------------------------------------------------
32 | Global element size: 0.5
33 | Number of quadtree elements: 50
34 | Mesh bounding box: -10.0, -10.0, 20.0, 20.0
35 | Size function: 0.5-0.43*exp(-0.03*((1.-x)*(2.-x)+(9.-y)*(9.-y)))
36 |
37 |
38 | #-----------------------------------------------------------
39 | # NODES
40 | #-----------------------------------------------------------
41 | Define nodes:
42 | 1.0, 1.0
43 | 10.0, 0.0
44 | 10.0, 10.0
45 | 0.0, 10.0
46 | 2.0, 2.0
47 | 2.0, 4.0
48 | 4.0, 4.0
49 | 4.0, 2.0
50 | 6.0, 5.0
51 | 7.0, 7.0
52 | 9.0, 4.0
53 | End nodes
54 |
55 | #-----------------------------------------------------------
56 | # BOUNDARIES
57 | #-----------------------------------------------------------
58 | # For every boundary an integer is assigned as marker.
59 | # Boundary edges are defined by:
60 | #
61 | # iStart, iEnd, edgeMarker, edgeRefinement
62 | #
63 | # > iStart and iEnd corresponds to the indices of the
64 | # nodes define above
65 | # > edgeMarker is an integer that is assigned to the
66 | # respective edge
67 | # > edgeRefinement is a double used to control the local
68 | # refinement near share edges (>0)
69 | #
70 | # > Exterior boundaries must be defined counter-clockwise
71 | # > Interior boundaries must be defined clockwise
72 | #
73 | #-----------------------------------------------------------
74 | Define exterior boundary: 1
75 | 0, 1, 0, 1.4
76 | 1, 2, 0, 1.4
77 | 2, 3, 0, 1.4
78 | 3, 0, 0, 1.4
79 | End exterior boundary
80 |
81 | Define interior boundary: 1
82 | 4, 5, 1, 1.6
83 | 5, 6, 1, 1.6
84 | 6, 7, 1, 1.6
85 | 7, 4, 1, 1.6
86 | End interior boundary
87 |
88 | Define interior boundary: 2
89 | 8, 9, 2, 1.5
90 | 9, 10, 2, 1.5
91 | 10, 8, 2, 1.5
92 | End interior boundary
93 | ```
94 |
95 | The mesh is created with
96 | ```sh
97 | ./bin/TMesh example.para
98 | ```
99 | Here is the generated mesh:
100 |
101 |
102 | ## Create a plot of your mesh
103 | The python script `share/python/plot_mesh.py` can create simple mesh plots from TMesh's output.
104 | Simply write TMesh's output to a text file
105 |
106 | ```sh
107 | ./bin/TMesh example.para > your_mesh.txt
108 | ```
109 |
110 | and then run the Python script with
111 |
112 | ```sh
113 | python share/python/plot_mesh.py your_mesh.txt your_meshplot.png
114 | ```
115 |
116 | ## Usage of C-Functions
117 | A detailed description on how to define a mesh is given in the examples under
118 | *src/tmesh/test*.
119 |
120 | Every mesh is defined by an exterior boundary and several more interior boundaries.
121 | These boundaries consist of edge segments, which connect two nodes.
122 | Besides this, it is also necessary to provide a size-function `size_fun` to the mesh, which
123 | defines the local element size in the domain.
124 | First, create a new mesh object:
125 | ```sh
126 | tmMesh *mesh = tmMesh_create(xy_min, xy_max, N, size_fun);
127 | ```
128 | Here, `xy_min` and `xy_max` define the bounding box of the entire domain, `N` is the number of elements that are stored in the underlying quadtree structure until a quad is refined.
129 | Next, define some vertices for the exterior boundary:
130 | ```sh
131 | tmNode *n0 = tmNode_create(mesh, xy0);
132 | tmNode *n1 = tmNode_create(mesh, xy1);
133 | tmNode *n2 = tmNode_create(mesh, xy2);
134 | ```
135 | `xy0`, `xy1`, `xy2` define the node coordinates, e.g. `tmDouble xy0[2] = { -1.0, -1.0 };`.
136 | Now create the exterior boundary and add the edge segments to it.
137 | **IMPORTANT**: Exteriror boundary edge segments must be defined in a **counter-clockwise** manner, such that all edge normals point to the inside of the domain.
138 | ```sh
139 | tmBdry *bdry_ext = tmMesh_addBdry(mesh, FALSE, 0);
140 | tmEdge *e0 = tmBdry_edgeCreate(bdry_ext, n0, n1, 0, 1.0);
141 | tmEdge *e1 = tmBdry_edgeCreate(bdry_ext, n1, n2, 0, 1.0);
142 | tmEdge *e2 = tmBdry_edgeCreate(bdry_ext, n2, n0, 0, 1.0);
143 | ```
144 | Interior boundaries are defined in a similar manner, but the segments must be defined in **clockwise** direction.
145 | ```sh
146 | tmNode *n3 = tmNode_create(mesh, xy3);
147 | tmNode *n4 = tmNode_create(mesh, xy4);
148 | tmNode *n5 = tmNode_create(mesh, xy5);
149 |
150 | tmBdry *bdry_int = tmMesh_addBdry(mesh, TRUE, 1);
151 | tmEdge *e3 = tmBdry_edgeCreate(bdry_int, n3, n4, 1, 1.0);
152 | tmEdge *e4 = tmBdry_edgeCreate(bdry_int, n4, n5, 1, 1.0);
153 | tmEdge *e5 = tmBdry_edgeCreate(bdry_int, n5, n3, 1, 1.0);
154 | ```
155 | Finally, the advancing-front meshing is performed using
156 | ```sh
157 | tmMesh_ADFMeshing(mesh);
158 | ```
159 | The final mesh can be printed to the command line with
160 | ```sh
161 | tmMesh_printMesh(mesh);
162 | ```
163 | and the output of this function can be rendered with a small Python script **plot_mesh.py**,
164 | which is located in the directory *share/python*.
165 |
166 |
167 |
168 | ### Custom Element Sizing
169 | The local element size can either be defined through a size function defined by the user or
170 | by the boundary edges. Elements near sharp angles are automatically refined.
171 |
172 |
173 |
174 | ## Benchmarks
175 |
176 |
177 | **TMesh** uses an adaptive quadtree structure to store vertices, edges and triangles in an accessible way. This allows to find any existing object in the meshing process with an average complexity of N log.
178 | The quadtree is refined and coarsened automatically as objects are inserted or removed from the structure.
179 |
180 | For profiling of a test-binary:
181 | * Compile with `-pg` (default in debugging mode)
182 | * Run the test binary
183 | * Profile with: `gprof test gmon.out > prof_output`
184 |
185 | ### Qtree search benchmark
186 | Here's a short benchmark of the underlying quadtree structure. Its the output from the test-function `test_tmQtree_performance()` for various numbers of vertices.
187 | | Nodes | Qtree | Brute Force |
188 | | :----------: | :----------: | :----------: |
189 | | 10000 | 0.0 s | 0.6 s |
190 | | 20000 | 0.1 s | 2.6 s |
191 | | 30000 | 0.3 s | 8.2 s |
192 | | 50000 | 0.8 s | 38.4 s |
193 | | 100000 | 3.5 s | 371.7 s |
194 |
195 |
196 | ### Triangular mesh generation benchmark
197 | This plot shows the performance of **TMesh** for the generation of to simple meshes,
198 | defined in the test function `test_tmFront_simpleMesh2()` and `test_tmBdry_sizeFun()`.
199 |
200 |
201 |
202 | ## Todos
203 | * Python-Interface
204 | * Delaunay-refinement for generated grids
205 | * Better output format of generated meshes, e.g. HDF5 or netCDF.
206 |
207 | ## Used Libraries
208 | * [The Better String Library](http://bstring.sourceforge.net)
209 | * [TinyExpr](https://github.com/codeplea/tinyexpr)
210 | * Some snippets from Zed Shaw's [Learn C the hard way](https://github.com/zedshaw/learn-c-the-hard-way-lectures)
211 |
212 | ## Sources
213 | * o'Rourke, Joseph. Computational geometry in C. Cambridge university press, 1998.
214 | * [Shewchuk, Jonathan R. Lecture Notes on Delaunay Mesh Generation, February 5, 2012](https://people.eecs.berkeley.edu/~jrs/meshpapers/delnotes.pdf)
215 | * [Jonathan R. Shewchuk's free course material on Mesh Generation and Geometry Processing in Graphics, Engineering, and Modeling ](https://people.eecs.berkeley.edu/~jrs/mesh/)
216 | * Lo, Daniel SH. Finite element mesh generation. CRC Press, 2014
217 | * Blazek, Jiri. Computational fluid dynamics: principles and applications. Butterworth-Heinemann, 2015
218 | * Zed A. Shaw, Learn C the Hard Way (this is where the testing structure and the list functions are coming from)
219 |
220 | ## License
221 | The project is licensed under the MIT License - see the LICENSE file for details.
222 |
--------------------------------------------------------------------------------
/TODO.md:
--------------------------------------------------------------------------------
1 | # ToDo List
2 | * Remove bug: Qtree stucks in loop, as several points lying directly on top of each other are created
3 |
--------------------------------------------------------------------------------
/doc/images/TMeshExample.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FloSewn/tmesh/28a3d7c5e6f3b7c8763dcd7433122e3a0a530e3d/doc/images/TMeshExample.png
--------------------------------------------------------------------------------
/doc/images/bdrySizeFun.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FloSewn/tmesh/28a3d7c5e6f3b7c8763dcd7433122e3a0a530e3d/doc/images/bdrySizeFun.png
--------------------------------------------------------------------------------
/doc/images/exampleMesh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FloSewn/tmesh/28a3d7c5e6f3b7c8763dcd7433122e3a0a530e3d/doc/images/exampleMesh.png
--------------------------------------------------------------------------------
/doc/images/performance.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FloSewn/tmesh/28a3d7c5e6f3b7c8763dcd7433122e3a0a530e3d/doc/images/performance.png
--------------------------------------------------------------------------------
/doc/images/qtree.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FloSewn/tmesh/28a3d7c5e6f3b7c8763dcd7433122e3a0a530e3d/doc/images/qtree.png
--------------------------------------------------------------------------------
/doc/images/qtree_gray.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FloSewn/tmesh/28a3d7c5e6f3b7c8763dcd7433122e3a0a530e3d/doc/images/qtree_gray.png
--------------------------------------------------------------------------------
/doc/images/tMesh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FloSewn/tmesh/28a3d7c5e6f3b7c8763dcd7433122e3a0a530e3d/doc/images/tMesh.png
--------------------------------------------------------------------------------
/share/cmake/compiler_flags.cmake:
--------------------------------------------------------------------------------
1 |
2 | ################################################################################
3 | # Define Build Type #
4 | ################################################################################
5 |
6 | # default build type
7 | if( NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES )
8 |
9 | # set the default build type
10 | message( STATUS "Setting build type to 'Debug' as none was specified." )
11 | set( CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE )
12 |
13 | # set the possible values of build type
14 | set_property( CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" )
15 |
16 | endif()
17 |
18 |
19 | ################################################################################
20 | # Compiler FLags #
21 | ################################################################################
22 |
23 | # set compiler definition
24 | if( CMAKE_C_COMPILER_ID STREQUAL "GNU" )
25 | string( APPEND MY_CMAKE_C_FLAGS "-DGNU" )
26 | elseif( CMAKE_C_COMPILER_ID STREQUAL "Intel" )
27 | string( APPEND MY_CMAKE_C_FLAGS "-DINTEL" )
28 | endif()
29 |
30 | # define coding standards
31 | if( CMAKE_C_COMPILER_ID STREQUAL "GNU" )
32 | string( APPEND MY_CMAKE_C_FLAGS " -std=c99" )
33 | elseif( CMAKE_C_COMPILER_ID STREQUAL "Intel" )
34 | string( APPEND MY_CMAKE_C_FLAGS " -std=c99" )
35 | endif()
36 |
37 |
38 | #################################
39 | # Compiler Flags (Debug Mode) #
40 | #################################
41 |
42 | # set debug compiler flags
43 | if( CMAKE_BUILD_TYPE STREQUAL "Debug" )
44 |
45 | # produce debugging information
46 | string( APPEND MY_CMAKE_C_FLAGS " -g" )
47 |
48 | # disable optimization
49 | string( APPEND MY_CMAKE_C_FLAGS " -O0" )
50 |
51 | # disable optimization
52 | string( APPEND MY_CMAKE_C_FLAGS " -pg" )
53 |
54 | if( CMAKE_C_COMPILER_ID STREQUAL "GNU" )
55 |
56 | # detect unused variables
57 | #string( APPEND MY_CMAKE_C_FLAGS " -Wunused-variable" )
58 |
59 | elseif( CMAKE_C_COMPILER_ID STREQUAL "Intel" )
60 |
61 | # detect unused variables
62 | # string( APPEND MY_CMAKE_C_FLAGS " -Wunused-variable" )
63 |
64 | endif()
65 |
66 | # overwrite compiler flags
67 | set(
68 | CMAKE_C_FLAGS_DEBUG ${MY_CMAKE_C_FLAGS}
69 | CACHE STRING "Flags used by the compiler during debug builds." FORCE
70 | )
71 |
72 | endif()
73 |
74 |
75 | #################################
76 | # Compiler Flags (Release Mode) #
77 | #################################
78 |
79 | # set release compiler flags
80 | if( CMAKE_BUILD_TYPE STREQUAL "Release" )
81 |
82 | # enable optimization
83 | string( APPEND MY_CMAKE_C_FLAGS " -O3" )
84 |
85 | if( CMAKE_C_COMPILER_ID STREQUAL "GNU" )
86 |
87 | # detect unused variables
88 | # string( APPEND MY_CMAKE_C_FLAGS " -Wunused-variable" )
89 |
90 | elseif( CMAKE_C_COMPILER_ID STREQUAL "Intel" )
91 |
92 | # detect unused variables
93 | # string( APPEND MY_CMAKE_C_FLAGS " -Wunused-variable" )
94 |
95 | endif()
96 |
97 | # overwrite compiler flags
98 | set(
99 | CMAKE_C_FLAGS_RELEASE ${MY_CMAKE_C_FLAGS}
100 | CACHE STRING "Flags used by the compiler during debug builds." FORCE
101 | )
102 |
103 | endif()
104 |
105 |
--------------------------------------------------------------------------------
/share/cmake/directories.cmake:
--------------------------------------------------------------------------------
1 | set( SRC ${CMAKE_SOURCE_DIR}/src )
2 | set( INC ${CMAKE_SOURCE_DIR}/include )
3 | set( LIB ${CMAKE_SOURCE_DIR}/lib )
4 | set( BIN ${CMAKE_SOURCE_DIR}/bin )
5 |
6 | # Define relative module path
7 | string( LENGTH ${CMAKE_SOURCE_DIR} CMAKE_SOURCE_DIR_LEN )
8 |
9 |
--------------------------------------------------------------------------------
/share/files/comment_test.para:
--------------------------------------------------------------------------------
1 | # This is a comment
2 |
3 | This is not a comment
4 |
5 |
6 | This!## is a comment
7 |
--------------------------------------------------------------------------------
/share/files/example.para:
--------------------------------------------------------------------------------
1 | #-----------------------------------------------------------
2 | # TMESH
3 | #-----------------------------------------------------------
4 | Global element size: 0.5
5 | Number of quadtree elements: 50
6 | Mesh bounding box: -10.0, -10.0, 20.0, 20.0
7 |
8 |
9 | #-----------------------------------------------------------
10 | # NODES
11 | #-----------------------------------------------------------
12 | Define nodes:
13 | 1.0, 1.0
14 | 10.0, 0.0
15 | 10.0, 10.0
16 | 0.0, 10.0
17 | 2.0, 2.0
18 | 2.0, 4.0
19 | 4.0, 4.0
20 | 4.0, 2.0
21 | 6.0, 5.0
22 | 7.0, 7.0
23 | 9.0, 4.0
24 | End nodes
25 |
26 | #-----------------------------------------------------------
27 | # BOUNDARIES
28 | #-----------------------------------------------------------
29 | # For every boundary an integer is assigned as marker.
30 | # Boundary edges are defined by:
31 | #
32 | # iStart, iEnd, edgeMarker, edgeRefinement
33 | #
34 | # > iStart and iEnd corresponds to the indices of the
35 | # nodes define above
36 | # > edgeMarker is an integer that is assigned to the
37 | # respective edge
38 | # > edgeRefinement is a double used to control the local
39 | # refinement near share edges (>0)
40 | #
41 | # > Exterior boundaries must be defined counter-clockwise
42 | # > Interior boundaries must be defined clockwise
43 | #
44 | #-----------------------------------------------------------
45 | Define exterior boundary: 1
46 | 0, 1, 1, 1.4
47 | 1, 2, 1, 1.4
48 | 2, 3, 1, 1.4
49 | 3, 0, 1, 1.4
50 | End exterior boundary
51 |
52 | Define interior boundary: 1
53 | 4, 5, 2, 1.6
54 | 5, 6, 2, 1.6
55 | 6, 7, 2, 1.6
56 | 7, 4, 2, 1.6
57 | End interior boundary
58 |
59 | Define interior boundary: 2
60 | 8, 9, 3, 1.5
61 | 9, 10, 3, 1.5
62 | 10, 8, 3, 1.5
63 | End interior boundary
64 |
--------------------------------------------------------------------------------
/share/files/simple.para:
--------------------------------------------------------------------------------
1 | #-----------------------------------------------------------
2 | # TMESH
3 | #-----------------------------------------------------------
4 | Global element size: 0.5
5 | Number of quadtree elements: 50
6 | Mesh bounding box: -10.0, -10.0, 20.0, 20.0
7 | Output format: STDOUT
8 |
9 |
10 | #-----------------------------------------------------------
11 | # NODES
12 | #-----------------------------------------------------------
13 | Define nodes:
14 | 1.0, 1.0
15 | 8.0, 0.0
16 | 5.0, 10.0
17 | 0.0, 10.0
18 | End nodes
19 |
20 | #-----------------------------------------------------------
21 | # BOUNDARIES
22 | #-----------------------------------------------------------
23 | Define exterior boundary: 1
24 | 0, 1, 0, 1.4
25 | 1, 2, 0, 0.4
26 | 2, 3, 0, 0.4
27 | 3, 0, 0, 0.4
28 | End exterior boundary
29 |
30 |
--------------------------------------------------------------------------------
/share/files/size_function.para:
--------------------------------------------------------------------------------
1 | #-----------------------------------------------------------
2 | # TMESH
3 | #-----------------------------------------------------------
4 | Global element size: 0.5
5 | Number of quadtree elements: 50
6 | Mesh bounding box: -10.0, -10.0, 20.0, 20.0
7 | Size function: 0.5-0.43*exp(-0.03*((1.-x)*(2.-x)+(9.-y)*(9.-y)))
8 |
9 | #-----------------------------------------------------------
10 | # NODES
11 | #-----------------------------------------------------------
12 | Define nodes:
13 | 1.0, 1.0
14 | 10.0, 0.0
15 | 10.0, 10.0
16 | 0.0, 10.0
17 | 2.0, 2.0
18 | 2.0, 4.0
19 | 4.0, 4.0
20 | 4.0, 2.0
21 | 6.0, 5.0
22 | 7.0, 7.0
23 | 9.0, 4.0
24 | End nodes
25 |
26 | #-----------------------------------------------------------
27 | # BOUNDARIES
28 | #-----------------------------------------------------------
29 | # For every boundary an integer is assigned as marker.
30 | # Boundary edges are defined by:
31 | #
32 | # iStart, iEnd, edgeMarker, edgeRefinement
33 | #
34 | # > iStart and iEnd corresponds to the indices of the
35 | # nodes define above
36 | # > edgeMarker is an integer that is assigned to the
37 | # respective edge
38 | # > edgeRefinement is a double used to control the local
39 | # refinement near share edges (>0)
40 | #
41 | # > Exterior boundaries must be defined counter-clockwise
42 | # > Interior boundaries must be defined clockwise
43 | #
44 | #-----------------------------------------------------------
45 | Define exterior boundary: 1
46 | 0, 1, 0, 1.4
47 | 1, 2, 0, 1.4
48 | 2, 3, 0, 1.4
49 | 3, 0, 0, 1.4
50 | End exterior boundary
51 |
52 | Define interior boundary: 1
53 | 4, 5, 1, 1.6
54 | 5, 6, 1, 1.6
55 | 6, 7, 1, 1.6
56 | 7, 4, 1, 1.6
57 | End interior boundary
58 |
59 | Define interior boundary: 2
60 | 8, 9, 2, 1.5
61 | 9, 10, 2, 1.5
62 | 10, 8, 2, 1.5
63 | End interior boundary
64 |
--------------------------------------------------------------------------------
/share/files/square.para:
--------------------------------------------------------------------------------
1 | #-----------------------------------------------------------
2 | # TMESH
3 | #-----------------------------------------------------------
4 | Global element size: 0.5
5 | Number of quadtree elements: 50
6 | Mesh bounding box: -10.0, -10.0, 20.0, 20.0
7 | Output format: STDOUT
8 |
9 |
10 | #-----------------------------------------------------------
11 | # NODES
12 | #-----------------------------------------------------------
13 | Define nodes:
14 | 0.0, 0.0
15 | 1.0, 0.0
16 | 1.0, 1.0
17 | 0.0, 1.0
18 | End nodes
19 |
20 | #-----------------------------------------------------------
21 | # BOUNDARIES
22 | #-----------------------------------------------------------
23 | Define exterior boundary: 1
24 | 0, 1, 1, 1.4
25 | 1, 2, 2, 1.4
26 | 2, 3, 3, 1.4
27 | 3, 0, 4, 1.4
28 | End exterior boundary
29 |
30 |
--------------------------------------------------------------------------------
/share/python/performance.py:
--------------------------------------------------------------------------------
1 | from matplotlib import pyplot as plt
2 | import numpy as np
3 | import sys, os
4 |
5 |
6 |
7 | def main():
8 | if len(sys.argv) < 2:
9 | print("performanc.py ")
10 | sys.exit(1)
11 |
12 | export_path = sys.argv[1]
13 |
14 | log_line = lambda x, Px, Py, n: (x**n) * np.exp(np.log(Py) - n * np.log(Px))
15 |
16 | # Performance with old version (bubble sort & other things)
17 | N0 = np.array([46, 534, 2164, 8592])
18 | T0 = np.array([2.25e-03, 1.12e-01, 2.01e+00, 4.14e+01])
19 | # Performance with version 0.2
20 | N1 = np.array([29, 106, 464, 1940, 11396, 45842, 184070, 1055218, 4221754])
21 | T1 = np.array([7.22e-04, 2.88e-03, 6.56e-03, 3.44e-02, 1.48e-01, 5.76e-01, 2.90e+00, 2.03e+01, 9.13e+01])
22 | # Performance with version 0.3 - automatic size function
23 | N2 = np.array([30, 95, 233, 1251, 4407, 81480, 238947, 1109863, 1808235,4293213])
24 | T2 = np.array([1.653000e-03, 1.732000e-03 ,5.852000e-03, 3.76e-02, 9.34e-02, 1.708676e+00, 5.747154e+00, 2.633492e+01, 4.615543e+01, 1.089948e+02])
25 |
26 | log_1 = log_line(N1, 5e-2, 2e-6, 1)
27 | #log_2 = log_line(N, 5e-2, 1e-9, 2)
28 |
29 | fig, ax = plt.subplots(1,1,figsize=(5,3))
30 | #ax.plot(N0, T0, c=(.5,.5,.9), ls='-', marker='o', lw=2.0, label='tMesh - v0.1')
31 | ax.plot(N1, T1, c=(.3,.3,.9), ls='-', marker='o', lw=2.0, label='Mesh A')
32 | ax.plot(N2, T2, c=(.9,.3,.9), ls='-', marker='o', lw=2.0, label='Mesh B')
33 |
34 | ax.plot(N1, log_1, c=(.1,.1,.1), ls='--', label='$\mathcal{O}(N)$')
35 | #ax.plot(N, log_2, c=(.5,.5,.5), ls='--', label='$\mathcal{O}(N^2)$')
36 |
37 | ax.legend()
38 |
39 | ax.set_yscale('log')
40 | ax.set_xscale('log')
41 |
42 | ax.set_xlabel('Number of triangles')
43 | ax.set_ylabel('Meshing time in seconds')
44 |
45 | #ax.grid(True)
46 |
47 | fig_path = os.path.join( export_path, 'performance')
48 | print("Exporting {:}".format(fig_path))
49 | plt.tight_layout()
50 | fig.savefig(fig_path + '.png', dpi=280)
51 | plt.close(fig)
52 | print("Done")
53 |
54 |
55 | if __name__ == '__main__': main()
56 |
--------------------------------------------------------------------------------
/share/python/plot_boundary.py:
--------------------------------------------------------------------------------
1 | '''
2 | Small function to plot the mesh boundaries
3 |
4 |
5 |
6 | '''
7 | from matplotlib import pyplot as plt
8 | import numpy as np
9 | import sys
10 |
11 | def read_meshdata(mesh_file):
12 | '''
13 | Function to read the raw mesh data
14 | '''
15 | with open(mesh_file, 'r') as reader:
16 | lines = reader.readlines()
17 | n_nodes = int(lines[0].split(' ')[1])
18 |
19 | nodes = np.zeros( (n_nodes, 2) )
20 | boundaries = {}
21 |
22 | for i in range(1, n_nodes+1):
23 | line = lines[i].replace('\n','').split('\t')
24 | nodes[i-1][0] = float(line[1])
25 | nodes[i-1][1] = float(line[2])
26 |
27 | lines = lines[n_nodes+1:]
28 | while (lines[0].split(' ')[0] == 'BOUNDARY'):
29 |
30 | boundary = int(lines[0].split(' ')[1])
31 | n_edges = int(lines[0].split(' ')[2])
32 | edges = []
33 | boundaries.update({ boundary : edges })
34 |
35 | for i in range(1, n_edges+1):
36 | line = lines[i].replace('\n','').split('\t')
37 | edge = (int(line[1]), int(line[2]))
38 | edges.append(edge)
39 |
40 | lines = lines[n_edges+1]
41 |
42 | return nodes, boundaries
43 |
44 |
45 | def main():
46 | ''' The main function '''
47 | if len(sys.argv) < 2:
48 | print("plot_boundary.py .dat")
49 | sys.exit(1)
50 |
51 | nodes, boundaries = read_meshdata(sys.argv[1])
52 |
53 |
54 | fig, ax = plt.subplots(1,1,figsize=(10,10))
55 |
56 | for i_bdry, edges in boundaries.items():
57 | for e in edges:
58 | ax.plot(nodes[e,0], nodes[e,1], c='k',
59 | lw=2.0, ls='-',marker='o')
60 |
61 |
62 | plt.show()
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | if __name__ == '__main__': main()
75 |
--------------------------------------------------------------------------------
/share/python/plot_mesh.py:
--------------------------------------------------------------------------------
1 | '''
2 | Small function to plot the mesh boundaries
3 |
4 |
5 |
6 | '''
7 | from matplotlib import pyplot as plt
8 | from matplotlib.patches import Polygon
9 | from matplotlib.collections import PatchCollection
10 | import numpy as np
11 | import sys, os
12 |
13 | TRI_PATCH = {'edgecolors' : ['k'],
14 | 'linewidths' : 0.9,
15 | 'facecolors' : ['w'],
16 | 'joinstyle' : 'round',
17 | 'capstyle' : 'round',
18 | 'alpha' : 1.0,
19 | 'cmap' : 'coolwarm'}
20 |
21 | def read_meshdata(mesh_file, read_front=False):
22 | '''
23 | Function to read the raw mesh data
24 | '''
25 | with open(mesh_file, 'r') as reader:
26 | lines = reader.readlines()
27 |
28 | # Filter out comments
29 | for i in range(len(lines)-1, -1, -1):
30 | identifier = lines[i].split(' ')[0]
31 | if (identifier == '>'):
32 | lines.pop(i)
33 |
34 | n_nodes = int(lines[0].split(' ')[1])
35 |
36 | nodes = np.zeros( (n_nodes, 2) )
37 | boundaries = {}
38 | bdry_marker = {}
39 | front_edges = []
40 | tris = []
41 |
42 | # Get node coordinates
43 | #----------------------------------------------------
44 | for i in range(1, n_nodes+1):
45 | line = lines[i].replace('\n','').split('\t')
46 | nodes[i-1][0] = float(line[1])
47 | nodes[i-1][1] = float(line[2])
48 |
49 | # Get boundary data
50 | #----------------------------------------------------
51 | lines = lines[n_nodes+1:]
52 | while (lines[0].split(' ')[0] == 'BOUNDARY'):
53 |
54 | boundary = int(lines[0].split(' ')[1])
55 | n_bdry_edges = int(lines[0].split(' ')[2])
56 | edges = []
57 | boundaries.update({ boundary : edges })
58 |
59 | for i in range(1, n_bdry_edges+1):
60 | line = lines[i].replace('\n','').split('\t')
61 | edge = (int(line[1]), int(line[2]))
62 | marker = int(line[3])
63 | edges.append(edge)
64 |
65 | if (marker in bdry_marker.keys()):
66 | bdry_marker[marker].append(edge)
67 | else:
68 | bdry_marker.update({marker : [edge]})
69 |
70 | lines = lines[n_bdry_edges+1:]
71 |
72 | # Get advancing front data
73 | #----------------------------------------------------
74 | if read_front:
75 | n_front_edges = int(lines[0].split(' ')[1])
76 |
77 | for i in range(1, n_front_edges+1):
78 | line = lines[i].replace('\n','').split('\t')
79 | edge = (int(line[1]), int(line[2]))
80 | front_edges.append(edge)
81 |
82 | lines = lines[n_front_edges+1:]
83 |
84 | # Get triangle data
85 | #----------------------------------------------------
86 | n_tris = int(lines[0].split(' ')[1])
87 |
88 | for i in range(1, n_tris+1):
89 | line = lines[i].replace('\n','').split('\t')
90 | tri = (int(line[1]), int(line[2]), int(line[3]))
91 | tris.append(tri)
92 |
93 |
94 | return nodes, boundaries, bdry_marker, front_edges, tris
95 |
96 |
97 | def main():
98 | ''' The main function '''
99 | if len(sys.argv) < 3:
100 | print("plot_boundary.py ")
101 | sys.exit(1)
102 |
103 | nodes, boundaries, bdry_marker, front_edges, tris = read_meshdata(sys.argv[1])
104 | export_path = sys.argv[2]
105 |
106 | i_plts = 0
107 |
108 | for step in range(len(tris), len(tris)-1-i_plts, -1):
109 |
110 | fig, ax = plt.subplots(1,1,figsize=(8,4))
111 | ax.set_aspect('equal')
112 |
113 | #for i_bdry, edges in boundaries.items():
114 | # for e in edges:
115 | # ax.plot(nodes[e,0], nodes[e,1], c='k',
116 | # lw=2.0, ls='-',marker='o')
117 |
118 | #for i, n in enumerate(nodes):
119 | #ax.plot(nodes[i,0], nodes[i,1], marker='o', c='k', ms=4)
120 | #ax.text(n[0],n[1],i, color='b')
121 |
122 | if step == len(tris):
123 | for e in front_edges:
124 | ax.plot(nodes[e,0], nodes[e,1], c='r',
125 | lw=1.0, ls='-') #,marker='o')
126 |
127 | tri_patches = []
128 | for i_tri, tri in enumerate(tris[:step]):
129 | tri_patches.append(Polygon([nodes[tri[i]] for i in range(3)]))
130 | #tri_centr = np.mean([nodes[tri[i]] for i in range(3)], axis=0)
131 | #ax.text(tri_centr[0], tri_centr[1], i_tri, color='k')
132 |
133 | tri_col = PatchCollection(tri_patches, **TRI_PATCH)
134 | ax.add_collection(tri_col)
135 |
136 | ax.set_xlim((nodes[:,0].min(),nodes[:,0].max()))
137 | ax.set_ylim((nodes[:,1].min(),nodes[:,1].max()))
138 | ax.set_axis_off()
139 |
140 | if i_plts > 0:
141 | fig_path = export_path + '_{:}'.format(len(tris)-step)
142 | else:
143 | fig_path = export_path
144 |
145 | if ( fig_path[-4:] != '.png' ):
146 | fig_path += '.png'
147 |
148 | print("Exporting {:}".format(fig_path))
149 | plt.tight_layout()
150 | fig.savefig(fig_path, dpi=280, transparent=True)
151 | plt.close(fig)
152 | print("Done")
153 |
154 |
155 |
156 |
157 | if __name__ == '__main__': main()
158 |
--------------------------------------------------------------------------------
/share/python/plot_qtree.py:
--------------------------------------------------------------------------------
1 | '''
2 | Small function to plot a quadtree structure
3 |
4 |
5 |
6 | '''
7 |
8 | from matplotlib.ticker import MaxNLocator
9 | from matplotlib.colors import BoundaryNorm
10 | from mpl_toolkits.axes_grid1 import make_axes_locatable
11 |
12 | from matplotlib import pyplot as plt
13 | from matplotlib.patches import Rectangle
14 | from matplotlib.collections import PatchCollection
15 | import numpy as np
16 | import sys, os
17 |
18 | QUAD_PATCH = {'edgecolors' : ['k'],
19 | 'linewidths' : 0.5,
20 | 'facecolors' : ['None'],
21 | 'joinstyle' : 'round',
22 | 'capstyle' : 'round',
23 | 'alpha' : 1.0,
24 | 'cmap' : 'Greys'}
25 |
26 | def read_quaddata(mesh_file):
27 | '''
28 | Function to read the raw quadtree data
29 | '''
30 | with open(mesh_file, 'r') as reader:
31 | lines = reader.readlines()
32 |
33 | # Filter out comments
34 | for i in range(len(lines)-1, -1, -1):
35 | identifier = lines[i].split(' ')[0]
36 | if (identifier == '>'):
37 | lines.pop(i)
38 |
39 | quads = []
40 | layers = []
41 |
42 | # Get quad coordinates
43 | #----------------------------------------------------
44 | for line in lines:
45 | cur_line = line.replace('\n','').split('\t')
46 | layer = int(cur_line[0])
47 | x_min = float(cur_line[1])
48 | y_min = float(cur_line[2])
49 | x_max = float(cur_line[3])
50 | y_max = float(cur_line[4])
51 | quads.append( [(x_min, y_min), (x_max, y_max)] )
52 | layers.append(layer)
53 |
54 | return np.array(quads), np.array(layers)
55 |
56 | def main():
57 | ''' The main function '''
58 | if len(sys.argv) < 3:
59 | print("plot_qtree.py .dat ")
60 | sys.exit(1)
61 |
62 | quads, layers = read_quaddata(sys.argv[1])
63 | export_path = sys.argv[2]
64 |
65 | fig, ax = plt.subplots(1,1,figsize=(24,18))
66 | ax.set_aspect('equal')
67 |
68 | quad_patches = []
69 | for i, q in enumerate(quads):
70 | width = q[1][0] - q[0][0]
71 | height = q[1][1] - q[0][1]
72 | quad_patches.append(Rectangle(q[0], width, height))
73 |
74 | '''
75 | # Add colormap for layers
76 | # ---------------------------------
77 | cmap = plt.get_cmap(QUAD_PATCH['cmap'])
78 | levels = MaxNLocator(nbins=25).tick_values(layers.min(),
79 | layers.max())
80 | norm = BoundaryNorm(levels, ncolors=cmap.N, clip=True)
81 | QUAD_PATCH.update({'norm':norm})
82 | '''
83 |
84 | quad_col = PatchCollection(quad_patches, **QUAD_PATCH)
85 | # quad_col.set_array(layers)
86 | ax.add_collection(quad_col)
87 |
88 | ax.set_xlim(( quads[:,0][:,0].min(), quads[:,1][:,0].max()) )
89 | ax.set_ylim(( quads[:,0][:,1].min(), quads[:,1][:,1].max()) )
90 | ax.set_axis_off()
91 |
92 | fig_path = os.path.join( export_path, 'qtree')
93 | print("Exporting {:}".format(fig_path))
94 | plt.tight_layout()
95 | fig.savefig(fig_path + '.png', dpi=300)
96 | plt.close(fig)
97 | print("Done")
98 |
99 | if __name__ == '__main__': main()
100 |
--------------------------------------------------------------------------------
/share/python/spiral.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | from matplotlib import pyplot as plt
3 | from numpy import pi, sin, cos
4 |
5 |
6 | def main():
7 |
8 | a = 2.5
9 | b = -3.4
10 | c = 6.5
11 | t = np.linspace(0.0, 5.*pi, 5000)
12 | x = (a + b * t) * cos(t) + c * sin(40*t)
13 | y = (a + b * t) * sin(t) + c * cos(40*t)
14 | fig, ax = plt.subplots(1,1,figsize=(10,10))
15 | ax.plot(x,y,lw=2.,c='r',ls='',marker='x')
16 | ax.set_xlim([-50,55])
17 | ax.set_ylim([-55,50])
18 | plt.show()
19 |
20 | if __name__ == '__main__': main()
21 |
--------------------------------------------------------------------------------
/src/tmesh/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | ##############################################################
2 | # MODULE: LEARN C THE HARD WAY
3 | ##############################################################
4 | # Define directories
5 | set( TMESH_DIR ${SRC}/tmesh )
6 | set( TMESH_INC ${TMESH_DIR}/include )
7 | set( TMESH_SRC ${TMESH_DIR}/src )
8 |
9 | # Define source files
10 | set( TMESH_MAIN
11 | ${TMESH_SRC}/bstrlib.c
12 | ${TMESH_SRC}/tinyexpr.c
13 | ${TMESH_SRC}/tmParam.c
14 | ${TMESH_SRC}/tmList.c
15 | ${TMESH_SRC}/tmNode.c
16 | ${TMESH_SRC}/tmEdge.c
17 | ${TMESH_SRC}/tmTri.c
18 | ${TMESH_SRC}/tmBdry.c
19 | ${TMESH_SRC}/tmFront.c
20 | ${TMESH_SRC}/tmMesh.c
21 | ${TMESH_SRC}/tmQtree.c
22 | )
23 |
24 | ##############################################################
25 | # LIBRARY: tmesh
26 | ##############################################################
27 | # define name
28 | set( TMESH_LIB tmesh )
29 |
30 | # add sources to library
31 | add_library( ${TMESH_LIB} STATIC ${TMESH_MAIN} )
32 | #add_library( ${TMESH_LIB} SHARED ${TMESH_MAIN} )
33 |
34 | # set public include
35 | target_include_directories( ${TMESH_LIB} PUBLIC
36 | $
37 | PRIVATE ${TMESH_SRC}
38 | )
39 |
40 | target_link_libraries( ${TMESH_LIB}
41 | m
42 | )
43 |
44 | install( TARGETS tmesh DESTINATION ${LIB} )
45 |
46 | ##############################################################
47 | # MAIN: tmesh
48 | ##############################################################
49 | set( MAINEXE_TMESH TMesh )
50 |
51 | add_executable( ${MAINEXE_TMESH}
52 | ${TMESH_SRC}/main.c
53 | )
54 |
55 | target_include_directories( ${MAINEXE_TMESH} PUBLIC
56 | $
57 | )
58 |
59 | target_link_libraries( ${MAINEXE_TMESH}
60 | tmesh
61 | m
62 | )
63 |
64 | # Install executables
65 | install( TARGETS ${MAINEXE_TMESH} RUNTIME DESTINATION ${BIN} )
66 |
67 |
68 | ##############################################################
69 | # TESTS: tmesh
70 | ##############################################################
71 | set( TESTEXE_TMESH tmesh_test )
72 | set( TESTDIR_TMESH ${TMESH_DIR}/test )
73 |
74 | add_executable( ${TESTEXE_TMESH}
75 | ${TESTDIR_TMESH}/tmList_tests.c
76 | ${TESTDIR_TMESH}/tmParam_tests.c
77 | ${TESTDIR_TMESH}/tmesh_tests.c
78 | ${TESTDIR_TMESH}/tmesh_cylinder.c
79 | ${TESTDIR_TMESH}/tmesh_examples.c
80 | ${TESTDIR_TMESH}/geom_tests.c
81 | ${TESTDIR_TMESH}/unit_tests.c
82 | )
83 |
84 | target_include_directories( ${TESTEXE_TMESH} PUBLIC
85 | $
86 | )
87 |
88 | target_link_libraries( ${TESTEXE_TMESH}
89 | tmesh
90 | m
91 | )
92 |
93 | # Install executables
94 | install( TARGETS ${TESTEXE_TMESH} RUNTIME DESTINATION ${BIN} )
95 |
96 |
97 |
98 |
--------------------------------------------------------------------------------
/src/tmesh/include/tmesh/bstrlib.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This source file is part of the bstring string library. This code was
3 | * written by Paul Hsieh in 2002-2015, and is covered by the BSD open source
4 | * license and the GPL. Refer to the accompanying documentation for details
5 | * on usage and license.
6 | */
7 |
8 | /*
9 | * bstrlib.h
10 | *
11 | * This file is the interface for the core bstring functions.
12 | */
13 |
14 | #ifndef BSTRLIB_INCLUDE
15 | #define BSTRLIB_INCLUDE
16 |
17 | #ifdef __cplusplus
18 | extern "C" {
19 | #endif
20 |
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 | #if !defined (BSTRLIB_VSNP_OK) && !defined (BSTRLIB_NOVSNP)
27 | # if defined (__TURBOC__) && !defined (__BORLANDC__)
28 | # define BSTRLIB_NOVSNP
29 | # endif
30 | #endif
31 |
32 | #define BSTR_ERR (-1)
33 | #define BSTR_OK (0)
34 | #define BSTR_BS_BUFF_LENGTH_GET (0)
35 |
36 | typedef struct tagbstring * bstring;
37 | typedef const struct tagbstring * const_bstring;
38 |
39 | /* Version */
40 | #define BSTR_VER_MAJOR 1
41 | #define BSTR_VER_MINOR 0
42 | #define BSTR_VER_UPDATE 0
43 |
44 | /* Copy functions */
45 | #define cstr2bstr bfromcstr
46 | extern bstring bfromcstr (const char * str);
47 | extern bstring bfromcstralloc (int mlen, const char * str);
48 | extern bstring bfromcstrrangealloc (int minl, int maxl, const char* str);
49 | extern bstring blk2bstr (const void * blk, int len);
50 | extern char * bstr2cstr (const_bstring s, char z);
51 | extern int bcstrfree (char * s);
52 | extern bstring bstrcpy (const_bstring b1);
53 | extern int bassign (bstring a, const_bstring b);
54 | extern int bassignmidstr (bstring a, const_bstring b, int left, int len);
55 | extern int bassigncstr (bstring a, const char * str);
56 | extern int bassignblk (bstring a, const void * s, int len);
57 |
58 | /* Destroy function */
59 | extern int bdestroy (bstring b);
60 |
61 | /* Space allocation hinting functions */
62 | extern int balloc (bstring s, int len);
63 | extern int ballocmin (bstring b, int len);
64 |
65 | /* Substring extraction */
66 | extern bstring bmidstr (const_bstring b, int left, int len);
67 |
68 | /* Various standard manipulations */
69 | extern int bconcat (bstring b0, const_bstring b1);
70 | extern int bconchar (bstring b0, char c);
71 | extern int bcatcstr (bstring b, const char * s);
72 | extern int bcatblk (bstring b, const void * s, int len);
73 | extern int binsert (bstring s1, int pos, const_bstring s2, unsigned char fill);
74 | extern int binsertblk (bstring s1, int pos, const void * s2, int len, unsigned char fill);
75 | extern int binsertch (bstring s1, int pos, int len, unsigned char fill);
76 | extern int breplace (bstring b1, int pos, int len, const_bstring b2, unsigned char fill);
77 | extern int bdelete (bstring s1, int pos, int len);
78 | extern int bsetstr (bstring b0, int pos, const_bstring b1, unsigned char fill);
79 | extern int btrunc (bstring b, int n);
80 |
81 | /* Scan/search functions */
82 | extern int bstricmp (const_bstring b0, const_bstring b1);
83 | extern int bstrnicmp (const_bstring b0, const_bstring b1, int n);
84 | extern int biseqcaseless (const_bstring b0, const_bstring b1);
85 | extern int biseqcaselessblk (const_bstring b, const void * blk, int len);
86 | extern int bisstemeqcaselessblk (const_bstring b0, const void * blk, int len);
87 | extern int biseq (const_bstring b0, const_bstring b1);
88 | extern int biseqblk (const_bstring b, const void * blk, int len);
89 | extern int bisstemeqblk (const_bstring b0, const void * blk, int len);
90 | extern int biseqcstr (const_bstring b, const char * s);
91 | extern int biseqcstrcaseless (const_bstring b, const char * s);
92 | extern int bstrcmp (const_bstring b0, const_bstring b1);
93 | extern int bstrncmp (const_bstring b0, const_bstring b1, int n);
94 | extern int binstr (const_bstring s1, int pos, const_bstring s2);
95 | extern int binstrr (const_bstring s1, int pos, const_bstring s2);
96 | extern int binstrcaseless (const_bstring s1, int pos, const_bstring s2);
97 | extern int binstrrcaseless (const_bstring s1, int pos, const_bstring s2);
98 | extern int bstrchrp (const_bstring b, int c, int pos);
99 | extern int bstrrchrp (const_bstring b, int c, int pos);
100 | #define bstrchr(b,c) bstrchrp ((b), (c), 0)
101 | #define bstrrchr(b,c) bstrrchrp ((b), (c), blength(b)-1)
102 | extern int binchr (const_bstring b0, int pos, const_bstring b1);
103 | extern int binchrr (const_bstring b0, int pos, const_bstring b1);
104 | extern int bninchr (const_bstring b0, int pos, const_bstring b1);
105 | extern int bninchrr (const_bstring b0, int pos, const_bstring b1);
106 | extern int bfindreplace (bstring b, const_bstring find, const_bstring repl, int pos);
107 | extern int bfindreplacecaseless (bstring b, const_bstring find, const_bstring repl, int pos);
108 |
109 | /* List of string container functions */
110 | struct bstrList {
111 | int qty, mlen;
112 | bstring * entry;
113 | };
114 | extern struct bstrList * bstrListCreate (void);
115 | extern int bstrListDestroy (struct bstrList * sl);
116 | extern int bstrListAlloc (struct bstrList * sl, int msz);
117 | extern int bstrListAllocMin (struct bstrList * sl, int msz);
118 |
119 | /* String split and join functions */
120 | extern struct bstrList * bsplit (const_bstring str, unsigned char splitChar);
121 | extern struct bstrList * bsplits (const_bstring str, const_bstring splitStr);
122 | extern struct bstrList * bsplitstr (const_bstring str, const_bstring splitStr);
123 | extern bstring bjoin (const struct bstrList * bl, const_bstring sep);
124 | extern bstring bjoinblk (const struct bstrList * bl, const void * s, int len);
125 | extern int bsplitcb (const_bstring str, unsigned char splitChar, int pos,
126 | int (* cb) (void * parm, int ofs, int len), void * parm);
127 | extern int bsplitscb (const_bstring str, const_bstring splitStr, int pos,
128 | int (* cb) (void * parm, int ofs, int len), void * parm);
129 | extern int bsplitstrcb (const_bstring str, const_bstring splitStr, int pos,
130 | int (* cb) (void * parm, int ofs, int len), void * parm);
131 |
132 | /* Miscellaneous functions */
133 | extern int bpattern (bstring b, int len);
134 | extern int btoupper (bstring b);
135 | extern int btolower (bstring b);
136 | extern int bltrimws (bstring b);
137 | extern int brtrimws (bstring b);
138 | extern int btrimws (bstring b);
139 |
140 | #if !defined (BSTRLIB_NOVSNP)
141 | extern bstring bformat (const char * fmt, ...);
142 | extern int bformata (bstring b, const char * fmt, ...);
143 | extern int bassignformat (bstring b, const char * fmt, ...);
144 | extern int bvcformata (bstring b, int count, const char * fmt, va_list arglist);
145 |
146 | #define bvformata(ret, b, fmt, lastarg) { \
147 | bstring bstrtmp_b = (b); \
148 | const char * bstrtmp_fmt = (fmt); \
149 | int bstrtmp_r = BSTR_ERR, bstrtmp_sz = 16; \
150 | for (;;) { \
151 | va_list bstrtmp_arglist; \
152 | va_start (bstrtmp_arglist, lastarg); \
153 | bstrtmp_r = bvcformata (bstrtmp_b, bstrtmp_sz, bstrtmp_fmt, bstrtmp_arglist); \
154 | va_end (bstrtmp_arglist); \
155 | if (bstrtmp_r >= 0) { /* Everything went ok */ \
156 | bstrtmp_r = BSTR_OK; \
157 | break; \
158 | } else if (-bstrtmp_r <= bstrtmp_sz) { /* A real error? */ \
159 | bstrtmp_r = BSTR_ERR; \
160 | break; \
161 | } \
162 | bstrtmp_sz = -bstrtmp_r; /* Doubled or target size */ \
163 | } \
164 | ret = bstrtmp_r; \
165 | }
166 |
167 | #endif
168 |
169 | typedef int (*bNgetc) (void *parm);
170 | typedef size_t (* bNread) (void *buff, size_t elsize, size_t nelem, void *parm);
171 |
172 | /* Input functions */
173 | extern bstring bgets (bNgetc getcPtr, void * parm, char terminator);
174 | extern bstring bread (bNread readPtr, void * parm);
175 | extern int bgetsa (bstring b, bNgetc getcPtr, void * parm, char terminator);
176 | extern int bassigngets (bstring b, bNgetc getcPtr, void * parm, char terminator);
177 | extern int breada (bstring b, bNread readPtr, void * parm);
178 |
179 | /* Stream functions */
180 | extern struct bStream * bsopen (bNread readPtr, void * parm);
181 | extern void * bsclose (struct bStream * s);
182 | extern int bsbufflength (struct bStream * s, int sz);
183 | extern int bsreadln (bstring b, struct bStream * s, char terminator);
184 | extern int bsreadlns (bstring r, struct bStream * s, const_bstring term);
185 | extern int bsread (bstring b, struct bStream * s, int n);
186 | extern int bsreadlna (bstring b, struct bStream * s, char terminator);
187 | extern int bsreadlnsa (bstring r, struct bStream * s, const_bstring term);
188 | extern int bsreada (bstring b, struct bStream * s, int n);
189 | extern int bsunread (struct bStream * s, const_bstring b);
190 | extern int bspeek (bstring r, const struct bStream * s);
191 | extern int bssplitscb (struct bStream * s, const_bstring splitStr,
192 | int (* cb) (void * parm, int ofs, const_bstring entry), void * parm);
193 | extern int bssplitstrcb (struct bStream * s, const_bstring splitStr,
194 | int (* cb) (void * parm, int ofs, const_bstring entry), void * parm);
195 | extern int bseof (const struct bStream * s);
196 |
197 | struct tagbstring {
198 | int mlen;
199 | int slen;
200 | unsigned char * data;
201 | };
202 |
203 | /* Accessor macros */
204 | #define blengthe(b, e) (((b) == (void *)0 || (b)->slen < 0) ? (int)(e) : ((b)->slen))
205 | #define blength(b) (blengthe ((b), 0))
206 | #define bdataofse(b, o, e) (((b) == (void *)0 || (b)->data == (void*)0) ? (char *)(e) : ((char *)(b)->data) + (o))
207 | #define bdataofs(b, o) (bdataofse ((b), (o), (void *)0))
208 | #define bdatae(b, e) (bdataofse (b, 0, e))
209 | #define bdata(b) (bdataofs (b, 0))
210 | #define bchare(b, p, e) ((((unsigned)(p)) < (unsigned)blength(b)) ? ((b)->data[(p)]) : (e))
211 | #define bchar(b, p) bchare ((b), (p), '\0')
212 |
213 | /* Static constant string initialization macro */
214 | #define bsStaticMlen(q,m) {(m), (int) sizeof(q)-1, (unsigned char *) ("" q "")}
215 | #if defined(_MSC_VER)
216 | # define bsStatic(q) bsStaticMlen(q,-32)
217 | #endif
218 | #ifndef bsStatic
219 | # define bsStatic(q) bsStaticMlen(q,-__LINE__)
220 | #endif
221 |
222 | /* Static constant block parameter pair */
223 | #define bsStaticBlkParms(q) ((void *)("" q "")), ((int) sizeof(q)-1)
224 |
225 | #define bcatStatic(b,s) ((bcatblk)((b), bsStaticBlkParms(s)))
226 | #define bfromStatic(s) ((blk2bstr)(bsStaticBlkParms(s)))
227 | #define bassignStatic(b,s) ((bassignblk)((b), bsStaticBlkParms(s)))
228 | #define binsertStatic(b,p,s,f) ((binsertblk)((b), (p), bsStaticBlkParms(s), (f)))
229 | #define bjoinStatic(b,s) ((bjoinblk)((b), bsStaticBlkParms(s)))
230 | #define biseqStatic(b,s) ((biseqblk)((b), bsStaticBlkParms(s)))
231 | #define bisstemeqStatic(b,s) ((bisstemeqblk)((b), bsStaticBlkParms(s)))
232 | #define biseqcaselessStatic(b,s) ((biseqcaselessblk)((b), bsStaticBlkParms(s)))
233 | #define bisstemeqcaselessStatic(b,s) ((bisstemeqcaselessblk)((b), bsStaticBlkParms(s)))
234 |
235 | /* Reference building macros */
236 | #define cstr2tbstr btfromcstr
237 | #define btfromcstr(t,s) { \
238 | (t).data = (unsigned char *) (s); \
239 | (t).slen = ((t).data) ? ((int) (strlen) ((char *)(t).data)) : 0; \
240 | (t).mlen = -1; \
241 | }
242 | #define blk2tbstr(t,s,l) { \
243 | (t).data = (unsigned char *) (s); \
244 | (t).slen = l; \
245 | (t).mlen = -1; \
246 | }
247 | #define btfromblk(t,s,l) blk2tbstr(t,s,l)
248 | #define bmid2tbstr(t,b,p,l) { \
249 | const_bstring bstrtmp_s = (b); \
250 | if (bstrtmp_s && bstrtmp_s->data && bstrtmp_s->slen >= 0) { \
251 | int bstrtmp_left = (p); \
252 | int bstrtmp_len = (l); \
253 | if (bstrtmp_left < 0) { \
254 | bstrtmp_len += bstrtmp_left; \
255 | bstrtmp_left = 0; \
256 | } \
257 | if (bstrtmp_len > bstrtmp_s->slen - bstrtmp_left) \
258 | bstrtmp_len = bstrtmp_s->slen - bstrtmp_left; \
259 | if (bstrtmp_len <= 0) { \
260 | (t).data = (unsigned char *)""; \
261 | (t).slen = 0; \
262 | } else { \
263 | (t).data = bstrtmp_s->data + bstrtmp_left; \
264 | (t).slen = bstrtmp_len; \
265 | } \
266 | } else { \
267 | (t).data = (unsigned char *)""; \
268 | (t).slen = 0; \
269 | } \
270 | (t).mlen = -__LINE__; \
271 | }
272 | #define btfromblkltrimws(t,s,l) { \
273 | int bstrtmp_idx = 0, bstrtmp_len = (l); \
274 | unsigned char * bstrtmp_s = (s); \
275 | if (bstrtmp_s && bstrtmp_len >= 0) { \
276 | for (; bstrtmp_idx < bstrtmp_len; bstrtmp_idx++) { \
277 | if (!isspace (bstrtmp_s[bstrtmp_idx])) break; \
278 | } \
279 | } \
280 | (t).data = bstrtmp_s + bstrtmp_idx; \
281 | (t).slen = bstrtmp_len - bstrtmp_idx; \
282 | (t).mlen = -__LINE__; \
283 | }
284 | #define btfromblkrtrimws(t,s,l) { \
285 | int bstrtmp_len = (l) - 1; \
286 | unsigned char * bstrtmp_s = (s); \
287 | if (bstrtmp_s && bstrtmp_len >= 0) { \
288 | for (; bstrtmp_len >= 0; bstrtmp_len--) { \
289 | if (!isspace (bstrtmp_s[bstrtmp_len])) break; \
290 | } \
291 | } \
292 | (t).data = bstrtmp_s; \
293 | (t).slen = bstrtmp_len + 1; \
294 | (t).mlen = -__LINE__; \
295 | }
296 | #define btfromblktrimws(t,s,l) { \
297 | int bstrtmp_idx = 0, bstrtmp_len = (l) - 1; \
298 | unsigned char * bstrtmp_s = (s); \
299 | if (bstrtmp_s && bstrtmp_len >= 0) { \
300 | for (; bstrtmp_idx <= bstrtmp_len; bstrtmp_idx++) { \
301 | if (!isspace (bstrtmp_s[bstrtmp_idx])) break; \
302 | } \
303 | for (; bstrtmp_len >= bstrtmp_idx; bstrtmp_len--) { \
304 | if (!isspace (bstrtmp_s[bstrtmp_len])) break; \
305 | } \
306 | } \
307 | (t).data = bstrtmp_s + bstrtmp_idx; \
308 | (t).slen = bstrtmp_len + 1 - bstrtmp_idx; \
309 | (t).mlen = -__LINE__; \
310 | }
311 |
312 | /* Write protection macros */
313 | #define bwriteprotect(t) { if ((t).mlen >= 0) (t).mlen = -1; }
314 | #define bwriteallow(t) { if ((t).mlen == -1) (t).mlen = (t).slen + ((t).slen == 0); }
315 | #define biswriteprotected(t) ((t).mlen <= 0)
316 |
317 | #ifdef __cplusplus
318 | }
319 | #endif
320 |
321 | #endif
322 |
323 |
--------------------------------------------------------------------------------
/src/tmesh/include/tmesh/dbg.h:
--------------------------------------------------------------------------------
1 | #ifndef __dbg_h__
2 | #define __dbg_h__
3 |
4 | #include
5 | #include
6 | #include
7 |
8 |
9 | /***************************************************
10 | * MACRO: debug
11 | * -------------------------------------------------
12 | * Translates any use of
13 | *
14 | * into an fprintf call to the stderr-function.
15 | *
16 | * stderr is a file stream to output all the
17 | * errors.
18 | **************************************************/
19 | #ifdef NDEBUG
20 | #define debug(M, ...)
21 | #else
22 | #define debug(M, ...) fprintf(stderr, "DEBUG: %s:%d: " M "\n",\
23 | __FILE__, __LINE__, ##__VA_ARGS__)
24 | #endif
25 |
26 | /***************************************************
27 | * MACRO: clean_errno
28 | * -------------------------------------------------
29 | * Used in other macros to get a safe, readable
30 | * version of errno.
31 | *
32 | * strerror-function:
33 | * Returns a pointer to a string that describes the
34 | * error passed in the argument
35 | **************************************************/
36 | #define clean_errno() (errno == 0 ? "None" : strerror(errno))
37 |
38 |
39 | /***************************************************
40 | * MACRO: log_err
41 | * -------------------------------------------------
42 | * Used to logging error messages to the user
43 | **************************************************/
44 | #define log_err(M, ...) fprintf(stderr, \
45 | "[ERROR] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, \
46 | clean_errno(), ##__VA_ARGS__)
47 |
48 |
49 | /***************************************************
50 | * MACRO: log_warn
51 | * -------------------------------------------------
52 | * Used to logging warning messages to the user
53 | **************************************************/
54 | #define log_warn(M, ...) fprintf(stderr, \
55 | "[WARN] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, \
56 | clean_errno(), ##__VA_ARGS__)
57 |
58 |
59 | /***************************************************
60 | * MACRO: log_info
61 | * -------------------------------------------------
62 | * Used to logging info messages to the user
63 | **************************************************/
64 | #define log_info(M, ...) fprintf(stderr, \
65 | "[INFO] (%s:%d) " M "\n", \
66 | __FILE__, __LINE__, ##__VA_ARGS__)
67 |
68 |
69 | /***************************************************
70 | * MACRO: check
71 | * -------------------------------------------------
72 | * Will make sure, that condition A is true.
73 | * If not, it will log the error M with variable
74 | * arguments for log_err and then jumps to the
75 | * functions error: for cleanup
76 | **************************************************/
77 | #define check(A, M, ...) if(!(A)) { \
78 | log_err(M, ##__VA_ARGS__); \
79 | errno=0; \
80 | goto error; }
81 |
82 |
83 | /***************************************************
84 | * MACRO: sentinel
85 | * -------------------------------------------------
86 | * This macro should be placed in any part of a
87 | * function that shouldn't run and, if it does,
88 | * it prints an error message and then jumps to
89 | * the error: label.
90 | **************************************************/
91 | #define sentinel(M, ...) { \
92 | log_err(M, ##__VA_ARGS__); \
93 | errno=0; \
94 | goto error; }
95 |
96 |
97 | /***************************************************
98 | * MACRO: check_mem
99 | * -------------------------------------------------
100 | * Makes sure that a pointer is valid, and if it
101 | * isn't, it reports it as an error with
102 | * "Out of memory"
103 | **************************************************/
104 | #define check_mem(A) check((A), "Out of memory.")
105 |
106 |
107 | /***************************************************
108 | * MACRO: check_debug
109 | * -------------------------------------------------
110 | * Checks and handles an error, but if the error
111 | * is common, then it doesn't bother reporting it
112 | **************************************************/
113 | #define check_debug(A, M, ...) if(!(A)) { \
114 | debug(M, ##__VA_ARGS__); \
115 | errno=0; \
116 | goto error; }
117 |
118 | #endif /* __dbg_h__ */
119 |
--------------------------------------------------------------------------------
/src/tmesh/include/tmesh/minunit.h:
--------------------------------------------------------------------------------
1 | #undef NDEBUG
2 | #ifndef _minunit_h
3 | #define _minunit_h
4 |
5 | #include
6 | #include
7 |
8 | #include "tmesh/dbg.h"
9 |
10 | static int tests_run;
11 |
12 | #define mu_suite_start() char *message = NULL
13 |
14 | #define mu_assert(test, message) if (!(test)) {\
15 | log_err(message); return message; }
16 |
17 | #define mu_run_test(test) debug("\n-----%s", " " #test); \
18 | message = test(); tests_run++; if (message) return message;
19 |
20 | #define mu_print_tests_run() debug("\nTESTS RUN: %d\n", tests_run)
21 |
22 | #define RUN_TESTS(name) int main(int argc, char *argv[]) {\
23 | argc = 0;argc++;\
24 | debug("----- RUNNING: %s", argv[0]);\
25 | printf("----\nRUNNING: %s\n", argv[0]);\
26 | char *result = name();\
27 | if (result != 0) {\
28 | printf("FAILED: %s\n", result);\
29 | }\
30 | else {\
31 | printf("ALL TESTS PASSED\n");\
32 | }\
33 | debug("Tests run: %d\n", tests_run);\
34 | exit(result != 0);\
35 | }
36 |
37 |
38 | #endif
39 |
40 | //argc = 1;
41 |
--------------------------------------------------------------------------------
/src/tmesh/include/tmesh/tinyexpr.h:
--------------------------------------------------------------------------------
1 | /*
2 | * TINYEXPR - Tiny recursive descent parser and evaluation engine in C
3 | *
4 | * Copyright (c) 2015-2018 Lewis Van Winkle
5 | *
6 | * http://CodePlea.com
7 | *
8 | * This software is provided 'as-is', without any express or implied
9 | * warranty. In no event will the authors be held liable for any damages
10 | * arising from the use of this software.
11 | *
12 | * Permission is granted to anyone to use this software for any purpose,
13 | * including commercial applications, and to alter it and redistribute it
14 | * freely, subject to the following restrictions:
15 | *
16 | * 1. The origin of this software must not be misrepresented; you must not
17 | * claim that you wrote the original software. If you use this software
18 | * in a product, an acknowledgement in the product documentation would be
19 | * appreciated but is not required.
20 | * 2. Altered source versions must be plainly marked as such, and must not be
21 | * misrepresented as being the original software.
22 | * 3. This notice may not be removed or altered from any source distribution.
23 | */
24 |
25 | #ifndef __TINYEXPR_H__
26 | #define __TINYEXPR_H__
27 |
28 |
29 | #ifdef __cplusplus
30 | extern "C" {
31 | #endif
32 |
33 |
34 |
35 | typedef struct te_expr {
36 | int type;
37 | union {double value; const double *bound; const void *function;};
38 | void *parameters[1];
39 | } te_expr;
40 |
41 |
42 | enum {
43 | TE_VARIABLE = 0,
44 |
45 | TE_FUNCTION0 = 8, TE_FUNCTION1, TE_FUNCTION2, TE_FUNCTION3,
46 | TE_FUNCTION4, TE_FUNCTION5, TE_FUNCTION6, TE_FUNCTION7,
47 |
48 | TE_CLOSURE0 = 16, TE_CLOSURE1, TE_CLOSURE2, TE_CLOSURE3,
49 | TE_CLOSURE4, TE_CLOSURE5, TE_CLOSURE6, TE_CLOSURE7,
50 |
51 | TE_FLAG_PURE = 32
52 | };
53 |
54 | typedef struct te_variable {
55 | const char *name;
56 | const void *address;
57 | int type;
58 | void *context;
59 | } te_variable;
60 |
61 |
62 |
63 | /* Parses the input expression, evaluates it, and frees it. */
64 | /* Returns NaN on error. */
65 | double te_interp(const char *expression, int *error);
66 |
67 | /* Parses the input expression and binds variables. */
68 | /* Returns NULL on error. */
69 | te_expr *te_compile(const char *expression, const te_variable *variables, int var_count, int *error);
70 |
71 | /* Evaluates the expression. */
72 | double te_eval(const te_expr *n);
73 |
74 | /* Prints debugging information on the syntax tree. */
75 | void te_print(const te_expr *n);
76 |
77 | /* Frees the expression. */
78 | /* This is safe to call on NULL pointers. */
79 | void te_free(te_expr *n);
80 |
81 |
82 | #ifdef __cplusplus
83 | }
84 | #endif
85 |
86 | #endif /*__TINYEXPR_H__*/
87 |
88 |
--------------------------------------------------------------------------------
/src/tmesh/include/tmesh/tmBdry.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This header file is part of the tmesh library.
3 | * This code was written by Florian Setzwein in 2020,
4 | * and is covered under the MIT License
5 | * Refer to the accompanying documentation for details
6 | * on usage and license.
7 | */
8 | #ifndef TMESH_TMBDRY_H
9 | #define TMESH_TMBDRY_H
10 |
11 | #include "tmesh/tmTypedefs.h"
12 |
13 | /**********************************************************
14 | * tmBdry: Boundary structure
15 | **********************************************************/
16 | typedef struct tmBdry {
17 |
18 | /*-------------------------------------------------------
19 | | Parent mesh properties
20 | -------------------------------------------------------*/
21 | tmMesh *mesh;
22 |
23 | /*-------------------------------------------------------
24 | | Properties of this boundary
25 | -------------------------------------------------------*/
26 | int no_edges;
27 | int is_interior;
28 | int index;
29 |
30 | tmDouble area;
31 |
32 | /*-------------------------------------------------------
33 | | Boundary edges
34 | -------------------------------------------------------*/
35 | tmEdge *edges_head;
36 | tmList *edges_stack;
37 | tmQtree *edges_qtree;
38 | tmListNode *mesh_pos;
39 |
40 | } tmBdry;
41 |
42 |
43 | /**********************************************************
44 | * Function: tmBdry_create()
45 | *----------------------------------------------------------
46 | * Create a new tmBdry structure and returns a pointer
47 | * to it.
48 | *----------------------------------------------------------
49 | * @return: Pointer to a new tmBdry structure
50 | **********************************************************/
51 | tmBdry *tmBdry_create(tmMesh *mesh,
52 | tmBool is_interior,
53 | int index);
54 |
55 | /**********************************************************
56 | * Function: tmBdry_destroy()
57 | *----------------------------------------------------------
58 | * Destroys a tmBdry structure and frees all its
59 | * memory.
60 | *----------------------------------------------------------
61 | * @param *mesh: pointer to a tmBdry to destroy
62 | *
63 | **********************************************************/
64 | void tmBdry_destroy(tmBdry *bdry);
65 |
66 | /**********************************************************
67 | * Function: tmBdry_edgeCreate()
68 | *----------------------------------------------------------
69 | * Function to create a new boundary edge
70 | *----------------------------------------------------------
71 | *
72 | **********************************************************/
73 | tmEdge *tmBdry_edgeCreate(tmBdry *bdry,
74 | tmNode *n1,
75 | tmNode *n2,
76 | tmIndex marker,
77 | tmDouble edgeSize);
78 |
79 | /**********************************************************
80 | * Function: tmBdry_addEdge()
81 | *----------------------------------------------------------
82 | * Function to add an edge to a tmBdry structure
83 | * This edge is the new head of the boundary structure
84 | *----------------------------------------------------------
85 | * @return: ListNode to tmEdge on the mesh's edge stack
86 | **********************************************************/
87 | tmListNode *tmBdry_addEdge(tmBdry *bdry, tmEdge *edge);
88 |
89 | /**********************************************************
90 | * Function: tmBdry_remEdge()
91 | *----------------------------------------------------------
92 | * Function to remove an edge from a tmBdry structure
93 | *----------------------------------------------------------
94 | *
95 | **********************************************************/
96 | void tmBdry_remEdge(tmBdry *bdry, tmEdge *edge);
97 |
98 | /**********************************************************
99 | * Function: tmBdry_isLeft()
100 | *----------------------------------------------------------
101 | * Check if an object is left of all boundary edges
102 | *----------------------------------------------------------
103 | * @param *edge: pointer to a tmEdge
104 | * @param *obj: pointer to object to check for
105 | * @param obj_type: object type specifier
106 | * @return boolean if object is located on the left of bdry
107 | **********************************************************/
108 | tmBool tmBdry_isLeft(tmBdry *bdry, void *obj, int obj_type);
109 |
110 | /**********************************************************
111 | * Function: tmBdry_isLeftOn()
112 | *----------------------------------------------------------
113 | * Check if an object is left of all boundary edges
114 | *----------------------------------------------------------
115 | * @param *edge: pointer to a tmEdge
116 | * @param *obj: pointer to object to check for
117 | * @param obj_type: object type specifier
118 | * @return boolean if object is located on the left of bdry
119 | **********************************************************/
120 | tmBool tmBdry_isLeftOn(tmBdry *bdry, void *obj, int obj_type);
121 |
122 | /**********************************************************
123 | * Function: tmBdry_isRight()
124 | *----------------------------------------------------------
125 | * Check if an object is right of all boundary edges
126 | *----------------------------------------------------------
127 | * @param *edge: pointer to a tmEdge
128 | * @param *obj: pointer to object to check for
129 | * @param obj_type: object type specifier
130 | * @return boolean if object is located on the left of bdry
131 | **********************************************************/
132 | tmBool tmBdry_isRight(tmBdry *bdry, void *obj, int obj_type);
133 |
134 | /**********************************************************
135 | * Function: tmBdry_isRightOn()
136 | *----------------------------------------------------------
137 | * Check if an object is right of all boundary edges
138 | *----------------------------------------------------------
139 | * @param *edge: pointer to a tmEdge
140 | * @param *obj: pointer to object to check for
141 | * @param obj_type: object type specifier
142 | * @return boolean if object is located on the left of bdry
143 | **********************************************************/
144 | tmBool tmBdry_isRightOn(tmBdry *bdry, void *obj, int obj_type);
145 |
146 | /**********************************************************
147 | * Function: tmBdry_isInside()
148 | *----------------------------------------------------------
149 | * Check if an object with position xy is inside of a
150 | * boundary which is enclosed by at least three edges,
151 | * using the Ray-Method.
152 | * If the object is located on the boundary edges,
153 | * it is treated as lying inside.
154 | *
155 | * Check out this source:
156 | * http://alienryderflex.com/polygon/
157 | *----------------------------------------------------------
158 | * @param *bdry: pointer to a tmBdry
159 | * @param xy: location to check for
160 | * @return boolean if object is located on the left of bdry
161 | **********************************************************/
162 | tmBool tmBdry_isInside(tmBdry *bdry, tmDouble xy[2]);
163 |
164 | /**********************************************************
165 | * Function: tmBdry_splitEdge()
166 | *----------------------------------------------------------
167 | * Split an edge by inserting a new node on its centroid
168 | * and splitting it into two new edges
169 | * This edge will be pointing from its node n1 to the new
170 | * node and a new edge will be created, which points
171 | * from the new node to n2.
172 | *----------------------------------------------------------
173 | * @param *bdry: pointer to bdry
174 | * @param *edge: pointer to a tmEdge
175 | * @return: pointer to newly created first edge
176 | **********************************************************/
177 | tmEdge *tmBdry_splitEdge(tmBdry *bdry, tmEdge *edge);
178 |
179 | /**********************************************************
180 | * Function: tmBdry_refine()
181 | *----------------------------------------------------------
182 | * Refine the edges of a boundary structure according to
183 | * a size function
184 | *----------------------------------------------------------
185 | * @param *bdry: pointer to bdry
186 | * @return:
187 | **********************************************************/
188 | void tmBdry_refine(tmBdry *bdry);
189 |
190 | /**********************************************************
191 | * Function: tmBdry_calcArea()
192 | *----------------------------------------------------------
193 | * Computes the area enclosed by the boundary and sets
194 | * it in the boundaries properties
195 | *
196 | * Reference:
197 | * https://www.wikihow.com/Calculate-the-Area-of-a-Polygon
198 | *----------------------------------------------------------
199 | * @param *bdry: pointer to bdry
200 | * @return:
201 | **********************************************************/
202 | void tmBdry_calcArea(tmBdry *bdry);
203 |
204 | /**********************************************************
205 | * Function: tmBdry_initSizeFun()
206 | *----------------------------------------------------------
207 | * Initializes the size function parameters for all
208 | * boundary nodes, based on respective boundary edge
209 | * lengths and angles.
210 | *----------------------------------------------------------
211 | * @param *bdry: pointer to bdry
212 | * @return:
213 | **********************************************************/
214 | void tmBdry_initSizeFun(tmBdry *bdry);
215 |
216 | #endif
217 |
--------------------------------------------------------------------------------
/src/tmesh/include/tmesh/tmEdge.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This header file is part of the tmesh library.
3 | * This code was written by Florian Setzwein in 2020,
4 | * and is covered under the MIT License
5 | * Refer to the accompanying documentation for details
6 | * on usage and license.
7 | */
8 | #ifndef TMESH_TMBDRYEDGE_H
9 | #define TMESH_TMBDRYEDGE_H
10 |
11 | #include "tmesh/tmTypedefs.h"
12 |
13 | /**********************************************************
14 | * tmEdge: Edge structure
15 | **********************************************************/
16 | typedef struct tmEdge {
17 |
18 | /*-------------------------------------------------------
19 | | Parent structures
20 | -------------------------------------------------------*/
21 | tmMesh *mesh;
22 | tmBdry *bdry;
23 | tmFront *front;
24 |
25 | /*-------------------------------------------------------
26 | | Edge centroid coordinates
27 | -------------------------------------------------------*/
28 | tmDouble xy[2];
29 | tmIndex index; /* Only used for the mesh-output */
30 | tmIndex bdry_marker;
31 |
32 | /*-------------------------------------------------------
33 | | Properties of this edge
34 | -------------------------------------------------------*/
35 | tmBool is_on_front;
36 | tmBool is_on_bdry;
37 | tmBool is_on_mesh;
38 | tmBool is_local_delaunay;
39 |
40 | tmListNode *stack_pos;
41 | tmListNode *qtree_pos;
42 | tmQtree *qtree;
43 |
44 | /*-------------------------------------------------------
45 | | Edge length
46 | -------------------------------------------------------*/
47 | tmDouble len;
48 |
49 | /*-------------------------------------------------------
50 | | Local mesh size factor
51 | -------------------------------------------------------*/
52 | tmDouble sizeFac;
53 |
54 | /*-------------------------------------------------------
55 | | Vector tangential to edge
56 | -------------------------------------------------------*/
57 | tmDouble dxy_t[2];
58 |
59 | /*-------------------------------------------------------
60 | | Vector normal to edge
61 | -------------------------------------------------------*/
62 | tmDouble dxy_n[2];
63 |
64 | /*-------------------------------------------------------
65 | | Edge start (n_1) and ending (n_2) nodes
66 | -------------------------------------------------------*/
67 | tmNode *n1;
68 | tmNode *n2;
69 |
70 | /*-------------------------------------------------------
71 | | Reference of edge in nodes edge lists
72 | -------------------------------------------------------*/
73 | tmListNode *n1_pos;
74 | tmListNode *n2_pos;
75 |
76 | /*-------------------------------------------------------
77 | | Adjacent triangles to this edge
78 | | t1: left triangle
79 | | t2: right triangle
80 | -------------------------------------------------------*/
81 | tmTri *t1;
82 | tmTri *t2;
83 |
84 | /*-------------------------------------------------------
85 | | Buffer variables ( e.g. for sorting )
86 | -------------------------------------------------------*/
87 | tmDouble dblBuf;
88 | tmIndex indBuf;
89 |
90 | } tmEdge;
91 |
92 | /**********************************************************
93 | * Function: tmEdge_create()
94 | *----------------------------------------------------------
95 | * Create a new tmEdge structure and return a pointer
96 | * to it.
97 | *----------------------------------------------------------
98 | * @param mesh: parent mesh of the new edge
99 | * @param n1,n2: Start and ending nodes of this edge
100 | * @param bdry: pointer to boundary the edge belongs to
101 | * @param type: flag for boundary / front / mesh edge
102 | * boundary -> 0
103 | * front -> 1
104 | * mesh -> 2
105 | * @param locSize: local size function value
106 | *
107 | * @return: Pointer to a new tmEdge structure
108 | **********************************************************/
109 | tmEdge *tmEdge_create(tmMesh *mesh,
110 | tmNode *n1,
111 | tmNode *n2,
112 | tmBdry *bdry,
113 | int edgeType);
114 |
115 | /**********************************************************
116 | * Function: tmEdge_destroy()
117 | *----------------------------------------------------------
118 | * Destroys a tmEdge structure and frees all its memory.
119 | *----------------------------------------------------------
120 | * @param *mesh: pointer to a tmEdge to destroy
121 | **********************************************************/
122 | void tmEdge_destroy(tmEdge *edge);
123 |
124 | /**********************************************************
125 | * Function: tmEdge_isLeft()
126 | *----------------------------------------------------------
127 | * Check if an object is left of the edge
128 | *----------------------------------------------------------
129 | * @param *edge: pointer to a tmEdge
130 | * @param *obj: pointer to object to check for
131 | * @param obj_type: object type specifier
132 | * @return boolean if object is located on the left of edge
133 | **********************************************************/
134 | tmBool tmEdge_isLeft(tmEdge *edge, void *obj, int obj_type);
135 |
136 | /**********************************************************
137 | * Function: tmEdge_isLeftOn()
138 | *----------------------------------------------------------
139 | * Check if an object is left of or on the edge
140 | *----------------------------------------------------------
141 | * @param *edge: pointer to a tmEdge
142 | * @param *obj: pointer to object to check for
143 | * @param obj_type: object type specifier
144 | * @return boolean if object is located on the left of edge
145 | **********************************************************/
146 | tmBool tmEdge_isLeftOn(tmEdge *edge, void *obj, int obj_type);
147 |
148 | /**********************************************************
149 | * Function: tmEdge_isRight()
150 | *----------------------------------------------------------
151 | * Check if an object is right of the edge
152 | *----------------------------------------------------------
153 | * @param *edge: pointer to a tmEdge
154 | * @param *obj: pointer to object to check for
155 | * @param obj_type: object type specifier
156 | * @return boolean if object is located on the left of edge
157 | **********************************************************/
158 | tmBool tmEdge_isRight(tmEdge *edge, void *obj, int obj_type);
159 |
160 | /**********************************************************
161 | * Function: tmEdge_isRightOn()
162 | *----------------------------------------------------------
163 | * Check if an object is right of or on the edge
164 | *----------------------------------------------------------
165 | * @param *edge: pointer to a tmEdge
166 | * @param *obj: pointer to object to check for
167 | * @param obj_type: object type specifier
168 | * @return boolean if object is located on the left of edge
169 | **********************************************************/
170 | tmBool tmEdge_isRightOn(tmEdge *edge, void *obj, int obj_type);
171 |
172 | /**********************************************************
173 | * Function: tmEdge_compareLen()
174 | *----------------------------------------------------------
175 | * Compare two edges according to their lengths
176 | *
177 | * -> Returns an integer less than zero, if length of e1 is
178 | * less than lenght of e2
179 | *
180 | * -> Returns zero, if length of e1 equals length of e2
181 | *
182 | * -> Returns an integer greater than zero if length of
183 | * e1 is greater than length of e2
184 | *----------------------------------------------------------
185 | * @param *e1, *e2: pointer to tmEdges to compare
186 | **********************************************************/
187 | int tmEdge_compareLen(tmEdge *e1, tmEdge *e2);
188 |
189 | /**********************************************************
190 | * Function: tmEdge_createNode()
191 | *----------------------------------------------------------
192 | * Create new node perpendicular to an edge with a distance
193 | * according to a size function
194 | *----------------------------------------------------------
195 | * @param edge: pointer to edge
196 | *
197 | **********************************************************/
198 | tmNode *tmEdge_createNode(tmEdge *edge);
199 |
200 | /**********************************************************
201 | * Function: tmEdge_isLocalDelaunay()
202 | *----------------------------------------------------------
203 | * Check if an edge is locally delaunay
204 | * If yes, put edge on the non-delaunay edge stack of the
205 | * mesh
206 | *----------------------------------------------------------
207 | * @param edge: pointer to edge
208 | *
209 | **********************************************************/
210 | void tmEdge_isDelaunay(tmEdge *edge);
211 |
212 | /**********************************************************
213 | * Function: tmEdge_flipEdge()
214 | *----------------------------------------------------------
215 | * Perform an edge flip, in order to get a new edge
216 | * which satisfies the delaunay constraint.
217 | * Definition:
218 | *
219 | * n2
220 | * /^^
221 | * / | \
222 | * / | \
223 | * e11 / | \ e22
224 | * / | \
225 | * / | \
226 | * / | \
227 | * p2 v t1 | t2 \ p1
228 | * \ | ^
229 | * \ |e /
230 | * \ | /
231 | * \ | /
232 | * e12 \ | / e21
233 | * \ | /
234 | * \ | /
235 | * v|/
236 | * n1
237 | *
238 | * e: (n1, n2) -> Flip to e*: (p1, p2)
239 | * t1: (n1, n2, p2) -> Flip to t1* : (n1, p1, p2)
240 | * t2: (n1, p1, n2) -> Flip to t2* : (n2, p2, p1)
241 | *
242 | * e11: (n2, p2) e12: (p2, n2)
243 | * e21: (n1, p1) e22: (p1, n2)
244 | *
245 | *----------------------------------------------------------
246 | * @param edge: pointer to edge to flip
247 | * @return : pointer to new edge
248 | *
249 | **********************************************************/
250 | tmEdge *tmEdge_flipEdge(tmEdge *e);
251 |
252 | #endif
253 |
--------------------------------------------------------------------------------
/src/tmesh/include/tmesh/tmFront.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This header file is part of the tmesh library.
3 | * This code was written by Florian Setzwein in 2020,
4 | * and is covered under the MIT License
5 | * Refer to the accompanying documentation for details
6 | * on usage and license.
7 | */
8 | #ifndef TMESH_TMFRONT_H
9 | #define TMESH_TMFRONT_H
10 |
11 | #include "tmesh/tmTypedefs.h"
12 |
13 | /**********************************************************
14 | * tmBdry: Advancing front structure
15 | **********************************************************/
16 | typedef struct tmFront {
17 |
18 | /*-------------------------------------------------------
19 | | Parent mesh properties
20 | -------------------------------------------------------*/
21 | tmMesh *mesh;
22 |
23 | /*-------------------------------------------------------
24 | | Properties of the advancing front
25 | -------------------------------------------------------*/
26 | int no_edges;
27 |
28 | /*-------------------------------------------------------
29 | | Advancing front edges
30 | -------------------------------------------------------*/
31 | tmEdge *edges_head;
32 | tmList *edges_stack;
33 | tmQtree *edges_qtree;
34 |
35 | } tmFront;
36 |
37 |
38 | /**********************************************************
39 | * Function: tmFront_create()
40 | *----------------------------------------------------------
41 | * Create a new tmFront structure and returns a pointer
42 | * to it.
43 | *----------------------------------------------------------
44 | * @return: Pointer to a new tmFront structure
45 | **********************************************************/
46 | tmFront *tmFront_create(tmMesh *mesh);
47 |
48 | /**********************************************************
49 | * Function: tmFront_destroy()
50 | *----------------------------------------------------------
51 | * Destroys a tmFront structure and frees all its
52 | * memory.
53 | *----------------------------------------------------------
54 | * @param *mesh: pointer to a tmFront to destroy
55 | *
56 | **********************************************************/
57 | void tmFront_destroy(tmFront *front);
58 |
59 | /**********************************************************
60 | * Function: tmFront_edgeCreate()
61 | *----------------------------------------------------------
62 | * Function to create a new edge on the advancing front
63 | *----------------------------------------------------------
64 | * @param front: advancing front structure to add edge to
65 | * @param n1,n2: start / ending node defining the edge
66 | * @param t: triangle that is located to the right
67 | * of the new edge
68 | *
69 | **********************************************************/
70 | tmEdge *tmFront_edgeCreate(tmFront *front,
71 | tmNode *n1,
72 | tmNode *n2,
73 | tmTri *t);
74 |
75 | /**********************************************************
76 | * Function: tmFront_addEdge()
77 | *----------------------------------------------------------
78 | * Function to add an edge to a tmFront structure
79 | * This edge is the new head of the front structure
80 | *----------------------------------------------------------
81 | * @param front: advancing front structure to add edge to
82 | * @param n1,n2: start / ending node defining the edge
83 | * @param t: triangle that is located to the right
84 | * of the new edge
85 | *
86 | **********************************************************/
87 | tmListNode *tmFront_addEdge(tmFront *front, tmEdge *edge);
88 |
89 | /**********************************************************
90 | * Function: tmFront_remEdge()
91 | *----------------------------------------------------------
92 | * Function to remove an edge from a tmBdry structure
93 | *----------------------------------------------------------
94 | *
95 | **********************************************************/
96 | void tmFront_remEdge(tmFront *front, tmEdge *edge);
97 |
98 | /**********************************************************
99 | * Function: tmFront_init()
100 | *----------------------------------------------------------
101 | * Function to initialize the advancing front of a mesh
102 | * --> Clone of all current boundaries
103 | *----------------------------------------------------------
104 | *
105 | **********************************************************/
106 | void tmFront_init(tmMesh *mesh);
107 |
108 | /**********************************************************
109 | * Function: tmFront_sortEdges()
110 | *----------------------------------------------------------
111 | * Function to sort the advancing front edges
112 | * according to their length in ascending order
113 | *----------------------------------------------------------
114 | *
115 | **********************************************************/
116 | void tmFront_sortEdges(tmMesh *mesh);
117 |
118 | /**********************************************************
119 | * Function: tmFront_advance()
120 | *----------------------------------------------------------
121 | * Function to advance the front edges
122 | * by one step
123 | *----------------------------------------------------------
124 | * @parameter mesh: pointer to mesh structure
125 | * @parameter eStart: pointer to advancing front edge
126 | * which will be advanced
127 | * @return boolean: if advancement was successfull
128 | *
129 | **********************************************************/
130 | tmBool tmFront_advance(tmMesh *mesh, tmEdge *e_ad);
131 |
132 | /**********************************************************
133 | * Function: tmFront_update()
134 | *----------------------------------------------------------
135 | * Function to update the front edges with a new node
136 | *----------------------------------------------------------
137 | * @param n: new node which is included in the front
138 | * @param e: current edge which will be replaced
139 | *
140 | **********************************************************/
141 | void tmFront_update(tmMesh *mesh,
142 | tmNode *n,
143 | tmEdge *e,
144 | tmTri *t);
145 |
146 | /**********************************************************
147 | * Function: tmFront_refine()
148 | *----------------------------------------------------------
149 | * Refine the edges of the advancing front structure
150 | * according to a size function
151 | *----------------------------------------------------------
152 | * @param *mesh: pointer to mesh containing the front
153 | * @return:
154 | **********************************************************/
155 | void tmFront_refine(tmMesh *mesh);
156 |
157 | /**********************************************************
158 | * Function: tmFront_splitEdge()
159 | *----------------------------------------------------------
160 | * Split an edge by inserting a new node on its centroid
161 | * and splitting it into two new edges
162 | * This edge will be pointing from its node n1 to the new
163 | * node and a new edge will be created, which points
164 | * from the new node to n2.
165 | *----------------------------------------------------------
166 | * @param *front: pointer to front
167 | * @param *edge: pointer to a tmEdge
168 | * @return: pointer to newly created first edge
169 | **********************************************************/
170 | tmEdge *tmFront_splitEdge(tmFront *front, tmEdge *edge);
171 |
172 | #endif
173 |
--------------------------------------------------------------------------------
/src/tmesh/include/tmesh/tmList.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This header file is part of the tmesh library.
3 | * This code was written by Florian Setzwein in 2020,
4 | * and is covered under the MIT License
5 | * Refer to the accompanying documentation for details
6 | * on usage and license.
7 | *
8 | * Most code in this file has been used from Zed Shaws Book
9 | * "Learn C the hard way"
10 | */
11 | #ifndef TMESH_TMLIST_H
12 | #define TMESH_TMLIST_H
13 |
14 |
15 | /**************************************************************
16 | * Defines for the handling with list structures
17 | **************************************************************/
18 | /* Returns the count of a list */
19 | #define tmList_count(A) ((A)->count)
20 | /* Return the value of the first list entry */
21 | #define tmList_first(A) ((A)->first != NULL ? (A)->first->value : NULL)
22 | /* Return the value of the last list entry */
23 | #define tmList_last(A) ((A)->last != NULL ? (A)->last->value : NULL)
24 | /* Return the first list entry */
25 | #define tmList_first_node(A) ((A)->first != NULL ? (A)->first : NULL)
26 | /* Return the last list entry */
27 | #define tmList_last_node(A) ((A)->last != NULL ? (A)->last : NULL)
28 | /* Perform a loop over a list structure */
29 | #define TMLIST_FOREACH(L, S, M, V) tmListNode *_node = NULL;\
30 | tmListNode *V = NULL;\
31 | for(V = _node = L->S; _node != NULL; V = _node = _node->M)
32 |
33 |
34 |
35 | /**************************************************************
36 | * ListNode Structure
37 | **************************************************************/
38 | struct tmListNode;
39 | typedef struct tmListNode {
40 | struct tmListNode *prev;
41 | struct tmListNode *next;
42 | void *value;
43 | } tmListNode;
44 |
45 | /**************************************************************
46 | * List Structure
47 | **************************************************************/
48 | typedef struct tmList {
49 | int count;
50 | tmListNode *first;
51 | tmListNode *last;
52 | } tmList;
53 |
54 | /*************************************************************
55 | * Function pointer to compare function
56 | *************************************************************/
57 | typedef int (*tmList_compare) (const void *a, const void *b);
58 |
59 |
60 |
61 | /**************************************************************
62 | * This function creates a new list structure
63 | **************************************************************/
64 | tmList *tmList_create();
65 |
66 | /**************************************************************
67 | * This function frees the memory of all ListNodes of a given
68 | * list structure
69 | **************************************************************/
70 | void tmList_destroy(tmList *list);
71 |
72 | /**************************************************************
73 | * This function frees all memory of the data that is stored
74 | * in a given list structure
75 | **************************************************************/
76 | void tmList_clear(tmList *list);
77 |
78 | /**************************************************************
79 | * This function frees all memory of a list structure
80 | **************************************************************/
81 | void tmList_clear_destroy(tmList *list);
82 |
83 | /**************************************************************
84 | * Push a new list node to the end of a list structure
85 | **************************************************************/
86 | void tmList_push(tmList *list, void *value);
87 |
88 | /**************************************************************
89 | * Remove the last node from a list structure
90 | **************************************************************/
91 | void *tmList_pop(tmList *list);
92 |
93 | /**************************************************************
94 | * Push a new list node to the beginning of a list structure
95 | **************************************************************/
96 | void tmList_unshift(tmList *list, void *value);
97 |
98 | /**************************************************************
99 | * Remove the first node from a list structure
100 | **************************************************************/
101 | void *tmList_shift(tmList *list);
102 |
103 | /**************************************************************
104 | * Remove a specific node from a list structure
105 | **************************************************************/
106 | void *tmList_remove(tmList *list, tmListNode *node);
107 |
108 | /**************************************************************
109 | * Appends to the end of and frees
110 | * the structure.
111 | **************************************************************/
112 | void *tmList_join(tmList *list1, tmList *list2);
113 |
114 | /*************************************************************
115 | * Splits a list at a specified Listnode
116 | *************************************************************/
117 | tmList *tmList_split(tmList *list1, int index);
118 |
119 |
120 | /*************************************************************
121 | * Bubble sort algorithm
122 | *************************************************************/
123 | int tmList_bubble_sort(tmList *list, tmList_compare cmp);
124 |
125 | /*************************************************************
126 | * Merge sort algorithm
127 | *************************************************************/
128 | tmList *tmList_merge_sort(tmList *list, tmList_compare cmp);
129 |
130 | #endif /* TMESH_TMLIST_H */
131 |
--------------------------------------------------------------------------------
/src/tmesh/include/tmesh/tmMesh.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This header file is part of the tmesh library.
3 | * This code was written by Florian Setzwein in 2020,
4 | * and is covered under the MIT License
5 | * Refer to the accompanying documentation for details
6 | * on usage and license.
7 | */
8 | #ifndef TMESH_TMMESH_H
9 | #define TMESH_TMMESH_H
10 |
11 | #include "tmesh/tmTypedefs.h"
12 |
13 | /**********************************************************
14 | * tmMesh: Triangular mesh structure
15 | **********************************************************/
16 | typedef struct tmMesh {
17 |
18 | /*-------------------------------------------------------
19 | | Mesh properties
20 | -------------------------------------------------------*/
21 | int qtree_max_obj;
22 | tmDouble xy_min[2];
23 | tmDouble xy_max[2];
24 |
25 | tmDouble areaBdry; /* Mesh domain area defined by bdry */
26 | tmDouble areaTris; /* Mesh domain area defined by tris */
27 |
28 | tmDouble globSize; /* Global mesh element size */
29 |
30 | /*-------------------------------------------------------
31 | | Mesh nodes
32 | -------------------------------------------------------*/
33 | tmNode *nodes_head;
34 | tmList *nodes_stack;
35 | int no_nodes;
36 | tmQtree *nodes_qtree;
37 |
38 | /*-------------------------------------------------------
39 | | Mesh boundaries
40 | -------------------------------------------------------*/
41 | int no_bdrys;
42 | tmList *bdry_stack;
43 |
44 | /*-------------------------------------------------------
45 | | Mesh advancing front edges
46 | -------------------------------------------------------*/
47 | tmFront *front;
48 |
49 | /*-------------------------------------------------------
50 | | Mesh size function
51 | -------------------------------------------------------*/
52 | tmSizeFun sizeFun;
53 | tmSizeFunUser sizeFunUser;
54 |
55 | /*-------------------------------------------------------
56 | | Mesh edges
57 | -------------------------------------------------------*/
58 | tmList *edges_stack;
59 | int no_edges;
60 | tmQtree *edges_qtree;
61 |
62 | /*-------------------------------------------------------
63 | | Stack to keep track of non-Delaunay edges
64 | -------------------------------------------------------*/
65 | tmList *delaunay_stack;
66 |
67 | /*-------------------------------------------------------
68 | | Mesh triangles
69 | -------------------------------------------------------*/
70 | tmTri *tris_head;
71 | tmList *tris_stack;
72 | int no_tris;
73 | tmQtree *tris_qtree;
74 | int no_tris_delaunay;
75 |
76 | } tmMesh;
77 |
78 |
79 | /**********************************************************
80 | * Function: tmMesh_create()
81 | *----------------------------------------------------------
82 | * Create a new tmMesh structure and returns a pointer
83 | * to it.
84 | *----------------------------------------------------------
85 | * @return: Pointer to a new tmMesh structure
86 | **********************************************************/
87 | tmMesh *tmMesh_create(tmDouble xy_min[2],
88 | tmDouble xy_max[2],
89 | int qtree_max_obj,
90 | tmDouble globSize,
91 | tmSizeFunUser sizeFunUser);
92 |
93 | /**********************************************************
94 | * Function: tmMesh_destroy()
95 | *----------------------------------------------------------
96 | * Destroys a tmMesh structure and frees all its
97 | * memory.
98 | *----------------------------------------------------------
99 | * @param *mesh: pointer to a tmMesh to destroy
100 | *
101 | **********************************************************/
102 | void tmMesh_destroy(tmMesh *mesh);
103 |
104 | /**********************************************************
105 | * Function: tmMesh_addNode()
106 | *----------------------------------------------------------
107 | * Function to add a tmNode to a tmMesh
108 | *----------------------------------------------------------
109 | * @return: tmNode index on the mesh's node stack
110 | **********************************************************/
111 | tmListNode *tmMesh_addNode(tmMesh *mesh, tmNode *node);
112 |
113 | /**********************************************************
114 | * Function: tmMesh_edgeCreate()
115 | *----------------------------------------------------------
116 | * Function to create a new edge for a tmMesh structure
117 | *----------------------------------------------------------
118 | * @param mesh: mesh for which the edge is defined
119 | * @param n1, n2: start/ending node of edge
120 | * @param t1, t2: triangle to the left / right of the edge
121 | **********************************************************/
122 | tmEdge *tmMesh_edgeCreate(tmMesh *mesh,
123 | tmNode *n1, tmNode *n2,
124 | tmTri *t1, tmTri *t2,
125 | tmIndex marker);
126 |
127 | /**********************************************************
128 | * Function: tmMesh_addEdge()
129 | *----------------------------------------------------------
130 | * Function to add an edge to a tmMesh structure
131 | *----------------------------------------------------------
132 | * @param mesh: mesh for which the edge is defined
133 | * @param edge: edge to add
134 | **********************************************************/
135 | tmListNode *tmMesh_addEdge(tmMesh *mesh, tmEdge *edge);
136 |
137 | /**********************************************************
138 | * Function: tmMesh_addTri()
139 | *----------------------------------------------------------
140 | * Function to add a tmTri to a tmMesh
141 | *----------------------------------------------------------
142 | * @return: tmTri index on the mesh's tri stack
143 | **********************************************************/
144 | tmListNode *tmMesh_addTri(tmMesh *mesh, tmTri *tri);
145 |
146 | /**********************************************************
147 | * Function: tmMesh_remNode()
148 | *----------------------------------------------------------
149 | * Function to remove a tmNode from a tmMesh
150 | *----------------------------------------------------------
151 | *
152 | **********************************************************/
153 | void tmMesh_remNode(tmMesh *mesh, tmNode *node);
154 |
155 | /**********************************************************
156 | * Function: tmMesh_remEdge()
157 | *----------------------------------------------------------
158 | * Function to remove an edge from a tmMesh structure
159 | *----------------------------------------------------------
160 | *
161 | **********************************************************/
162 | void tmMesh_remEdge(tmMesh *mesh, tmEdge *edge);
163 |
164 | /**********************************************************
165 | * Function: tmMesh_remTri()
166 | *----------------------------------------------------------
167 | * Function to remove a tmTri from a tmMesh
168 | *----------------------------------------------------------
169 | *
170 | **********************************************************/
171 | void tmMesh_remTri(tmMesh *mesh, tmTri *tri);
172 |
173 | /**********************************************************
174 | * Function: tmMesh_addBdry()
175 | *----------------------------------------------------------
176 | * Function to add a boundary structure to a tmMesh
177 | *----------------------------------------------------------
178 | * @return: tmBdry pointer
179 | **********************************************************/
180 | tmBdry *tmMesh_addBdry(tmMesh *mesh,
181 | tmBool is_interior,
182 | int index);
183 |
184 | /**********************************************************
185 | * Function: tmMesh_remBdry()
186 | *----------------------------------------------------------
187 | * Function to remove a boundary structure from a tmMesh
188 | *----------------------------------------------------------
189 | *
190 | **********************************************************/
191 | void tmMesh_remBdry(tmMesh *mesh, tmBdry *bdry);
192 |
193 | /**********************************************************
194 | * Function: tmMesh_objInside()
195 | *----------------------------------------------------------
196 | * Function to check wether an object at position xy
197 | * is contained within the mesh boundary
198 | *----------------------------------------------------------
199 | * @param mesh
200 | * @param xy
201 | **********************************************************/
202 | tmBool tmMesh_objInside(tmMesh *mesh, tmDouble xy[2]);
203 |
204 | /**********************************************************
205 | * Function: tmMesh_printMesh()
206 | *----------------------------------------------------------
207 | * Fuction to print out the mesh data
208 | *----------------------------------------------------------
209 | * @param mesh: pointer to mesh structure
210 | **********************************************************/
211 | void tmMesh_printMesh(tmMesh *mesh);
212 |
213 | /**********************************************************
214 | * Function: tmMesh_printMeshIncomflow()
215 | *----------------------------------------------------------
216 | * Fuction to print out the mesh data in the format for
217 | * the incomflow solver
218 | *----------------------------------------------------------
219 | * @param mesh: pointer to mesh structure
220 | **********************************************************/
221 | void tmMesh_printMeshIncomflow(tmMesh *mesh);
222 |
223 | /**********************************************************
224 | * Function: tmMesh_adfMeshing()
225 | *----------------------------------------------------------
226 | * Function to perform the advancing front loop
227 | * until either no edges are available anymore or until
228 | * a final iteration is reached
229 | *----------------------------------------------------------
230 | *
231 | **********************************************************/
232 | void tmMesh_ADFMeshing(tmMesh *mesh);
233 |
234 | /**********************************************************
235 | * Function: tmMesh_delaunayFlip()
236 | *----------------------------------------------------------
237 | * Function to perform the flip algorithm on a triangulated
238 | * mesh, in order to obtain a triangulation that is delaunay
239 | *----------------------------------------------------------
240 | *
241 | **********************************************************/
242 | void tmMesh_delaunayFlip(tmMesh *mesh);
243 |
244 | /**********************************************************
245 | * Function: tmMesh_setTriNeighbors()
246 | *----------------------------------------------------------
247 | * Sets for every triangle the connectivity to its neigbors
248 | * This is done, when the advancing front meshing
249 | * has finished.
250 | *----------------------------------------------------------
251 | * @param mesh: the mesh structure
252 | **********************************************************/
253 | void tmMesh_setTriNeighbors(tmMesh *mesh);
254 |
255 | /**********************************************************
256 | * Function: tmMesh_calcArea()
257 | *----------------------------------------------------------
258 | * Function to compute the area enclosed by the entire
259 | * mesh domain
260 | *----------------------------------------------------------
261 | * @param mesh: mesh for which the edge is defined
262 | **********************************************************/
263 | void tmMesh_calcArea(tmMesh *mesh);
264 |
265 | /**********************************************************
266 | * Function: tmMesh_getTriFromCoords()
267 | *----------------------------------------------------------
268 | * Function returns a triangle which contains a given
269 | * point (x,y). If the point is located on the edge
270 | * of two triangles, the first one that has been located
271 | * on the tri-stack will be chosen.
272 | *----------------------------------------------------------
273 | * @param mesh: mesh for which the edge is defined
274 | * @param xy: point coordinates
275 | * @return: triangle, in which xy is contained.
276 | **********************************************************/
277 | tmTri* tmMesh_getTriFromCoords(tmMesh *mesh, tmDouble xy[2]);
278 |
279 | /**********************************************************
280 | * Function: tmMesh_refineLocal()
281 | *----------------------------------------------------------
282 | * Add a new node at a specified location in the mesh
283 | * and subsequently re-triangulate the mesh in this area.
284 | *----------------------------------------------------------
285 | * @param mesh: the mesh structure
286 | * @param xy: coordinates of the new node to insert
287 | *
288 | **********************************************************/
289 | void tmMesh_refineLocally(tmMesh *mesh, tmDouble xy[2]);
290 |
291 | /**********************************************************
292 | * Function: tmMesh_sizeFun()
293 | *----------------------------------------------------------
294 | * Define a global size function for the mesh
295 | *----------------------------------------------------------
296 | * @param mesh: the mesh structure
297 | * @param xy: coordinates to evaluate the size function
298 | *
299 | **********************************************************/
300 | tmDouble tmMesh_sizeFun(tmMesh *mesh, tmDouble xy[2]);
301 |
302 | #endif
303 |
--------------------------------------------------------------------------------
/src/tmesh/include/tmesh/tmNode.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This header file is part of the tmesh library.
3 | * This code was written by Florian Setzwein in 2020,
4 | * and is covered under the MIT License
5 | * Refer to the accompanying documentation for details
6 | * on usage and license.
7 | */
8 | #ifndef TMESH_TMNODE_H
9 | #define TMESH_TMNODE_H
10 |
11 | #include "tmesh/tmTypedefs.h"
12 |
13 |
14 | /**********************************************************
15 | * tmNode: Node
16 | **********************************************************/
17 | typedef struct tmNode {
18 |
19 | /*-------------------------------------------------------
20 | | Parent mesh properties
21 | -------------------------------------------------------*/
22 | tmMesh *mesh;
23 |
24 | /*-------------------------------------------------------
25 | | Node coordinates
26 | -------------------------------------------------------*/
27 | tmDouble xy[2];
28 | tmIndex index; /* Only used for the mesh-output */
29 | tmBool is_active; /* Every node is active by default */
30 |
31 | /*-------------------------------------------------------
32 | | Properties of this node and its state
33 | -------------------------------------------------------*/
34 | tmListNode *stack_pos;
35 | tmListNode *qtree_pos;
36 | tmQtree *qtree;
37 |
38 | /*-------------------------------------------------------
39 | | Boundary properties if node is located on a boundary
40 | -------------------------------------------------------*/
41 | tmBool on_bdry;
42 | tmList *bdry_edges;
43 | int n_bdry_edges;
44 |
45 | /*-------------------------------------------------------
46 | | All adjacent front edges to this node
47 | -------------------------------------------------------*/
48 | tmBool on_front;
49 | tmList *front_edges;
50 | int n_front_edges;
51 |
52 | /*-------------------------------------------------------
53 | | All mesh edges to this node
54 | -------------------------------------------------------*/
55 | tmList *mesh_edges;
56 | int n_mesh_edges;
57 |
58 | /*-------------------------------------------------------
59 | | All adjacent triangles to this node
60 | -------------------------------------------------------*/
61 | tmList *tris;
62 | int n_tris;
63 |
64 | /*-------------------------------------------------------
65 | | Buffer variables ( e.g. for sorting )
66 | -------------------------------------------------------*/
67 | tmDouble dblBuf;
68 | tmIndex indBuf;
69 |
70 | /*-------------------------------------------------------
71 | | Size function properties if node is on boundary
72 | -------------------------------------------------------*/
73 | tmDouble rho;
74 | tmDouble k;
75 |
76 | } tmNode;
77 |
78 |
79 | /**********************************************************
80 | * Function: tmNode_create()
81 | *----------------------------------------------------------
82 | * Create a new tmNode structure and returns a pointer
83 | * to it.
84 | *----------------------------------------------------------
85 | * @param mesh: parent mesh of the new node
86 | * @param xy: Node coordinates
87 | *
88 | * @return: Pointer to a new tmNode structure
89 | **********************************************************/
90 | tmNode *tmNode_create(tmMesh *mesh, tmDouble xy[2]);
91 |
92 | /**********************************************************
93 | * Function: tmNode_destroy()
94 | *----------------------------------------------------------
95 | * Destroys a tmNode structure and frees all its memory.
96 | *----------------------------------------------------------
97 | * @param *mesh: pointer to a tmNode to destroy
98 | *
99 | * @return: Returns TRUE if method works
100 | **********************************************************/
101 | void tmNode_destroy(tmNode *node);
102 |
103 | /**********************************************************
104 | * Function: tmNode_getBdryEdgeIn()
105 | *----------------------------------------------------------
106 | * Returns a list of ingoing boundary edges
107 | *----------------------------------------------------------
108 | * @param *mesh: pointer to a tmNode
109 | *
110 | * @return: tmList of tmEdges
111 | **********************************************************/
112 | tmList *tmNode_getBdryEdgeIn(tmNode *node);
113 |
114 | /**********************************************************
115 | * Function: tmNode_getBdryEdgeOut()
116 | *----------------------------------------------------------
117 | * Returns a list of outgoing boundary edges
118 | *----------------------------------------------------------
119 | * @param *mesh: pointer to a tmNode
120 | *
121 | * @return: tmList of tmEdges
122 | **********************************************************/
123 | tmList *tmNode_getBdryEdgeOut(tmNode *node);
124 |
125 | /**********************************************************
126 | * Function: tmNode_getFrontEdgeIn()
127 | *----------------------------------------------------------
128 | * Returns a list of ingoing advancing front edges
129 | *----------------------------------------------------------
130 | * @param *mesh: pointer to a tmNode
131 | *
132 | * @return: tmList of tmEdges
133 | **********************************************************/
134 | tmList *tmNode_getFrontEdgeIn(tmNode *node);
135 |
136 | /**********************************************************
137 | * Function: tmNode_getFrontEdgeOut()
138 | *----------------------------------------------------------
139 | * Returns a list of outgoing advancing front edges
140 | *----------------------------------------------------------
141 | * @param *mesh: pointer to a tmNode
142 | *
143 | * @return: tmList of tmEdges
144 | **********************************************************/
145 | tmList *tmNode_getFrontEdgeOut(tmNode *node);
146 |
147 | /**********************************************************
148 | * Function: tmNode_getNbrsFromSizeFun
149 | *----------------------------------------------------------
150 | * Function to estimate neighbouring nodes of a given node
151 | * within a range that is estimated from a sizefunction
152 | *----------------------------------------------------------
153 | *
154 | **********************************************************/
155 | tmList *tmNode_getNbrsFromSizeFun(tmNode *node);
156 |
157 | /**********************************************************
158 | * Function: tmNode_getFrontNbrs
159 | *----------------------------------------------------------
160 | * Returns a list of tmNodes that are connected to a
161 | * given tmNode through advancing front edges
162 | *
163 | *----------------------------------------------------------
164 | *
165 | **********************************************************/
166 | tmList *tmNode_getFrontNbrs(tmNode *node);
167 |
168 | /**********************************************************
169 | * Function: tmNode_getAdjFrontEdge()
170 | *----------------------------------------------------------
171 | * Checks for a node n wether it is connected to a
172 | * node m through an advancing front edge.
173 | * If yes, the edge is returned - otherwise a NULL pointer
174 | * is returned
175 | *
176 | *----------------------------------------------------------
177 | * @param n: node whose advancing front edges are checked
178 | * @param m: node which is search for on edges other ends
179 | *
180 | **********************************************************/
181 | tmEdge *tmNode_getAdjFrontEdge(tmNode *n, tmNode *m);
182 |
183 | /**********************************************************
184 | * Function: tmNode_isValid()
185 | *----------------------------------------------------------
186 | * Checks, if a node is valid for the mesh genereation
187 | * process. The node may not be located too close
188 | * to preceeding edges in its vicinity in order to be valid
189 | *
190 | *----------------------------------------------------------
191 | * @param node: node to be checked
192 | *
193 | **********************************************************/
194 | tmBool tmNode_isValid(tmNode *node);
195 |
196 | #endif
197 |
--------------------------------------------------------------------------------
/src/tmesh/include/tmesh/tmParam.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This header file is part of the tmesh library.
3 | * This code was written by Florian Setzwein in 2020,
4 | * and is covered under the MIT License
5 | * Refer to the accompanying documentation for details
6 | * on usage and license.
7 | */
8 | #ifndef TMESH_TMPARAM_H
9 | #define TMESH_TMPARAM_H
10 |
11 | #include
12 | #include
13 | #include
14 |
15 | #include "tmesh/tmTypedefs.h"
16 | #include "tmesh/bstrlib.h"
17 |
18 | #define FILIO_ERR -1
19 |
20 | /*************************************************************
21 | * Parameter file structure
22 | *************************************************************/
23 | struct tmParam;
24 | typedef struct tmParam {
25 | const char *path; /* Path of file */
26 | bstring txt; /* bstring with file data */
27 | struct bstrList *txtlist; /* file, splitted for newlines */
28 |
29 | long length; /* Number of chars in total file*/
30 | /* -> including '\0' at end */
31 | int nlines; /* Number of lines in total file*/
32 |
33 | } tmParam;
34 |
35 | /*************************************************************
36 | * Function to create a new parameter file reader structure
37 | *************************************************************/
38 | tmParam *tmParam_create(const char *file_path);
39 |
40 | /*************************************************************
41 | * Function to destroy a file reader structure
42 | *************************************************************/
43 | int tmParam_destroy(tmParam *file);
44 |
45 | /*************************************************************
46 | * Function returns a bstring list of lines, that
47 | * do not contain a certain specifier
48 | *************************************************************/
49 | struct bstrList *tmParam_popLinesWith(struct bstrList *txtlist,
50 | const char *fltr);
51 |
52 | /*************************************************************
53 | * Function returns a bstring list of lines, that
54 | * do contain a certain specifier
55 | *************************************************************/
56 | struct bstrList *tmParam_getLinesWith(struct bstrList *txtlist,
57 | const char *fltr);
58 |
59 | /*************************************************************
60 | * This function removes all strings in the file that are
61 | * located behind a "comment" identifiert and the next
62 | * new line character
63 | *************************************************************/
64 | struct bstrList *tmParam_removeComments(struct bstrList *txtlist,
65 | const char *fltr);
66 |
67 | /*************************************************************
68 | * Function searches for a specifier in a bstrList.
69 | * The parameter behind the specifier is then extracted
70 | * from the file and stored into .
71 | * The value is casted to a prescribed type
72 | * type = 0: integer
73 | * type = 1: double
74 | * type = 2: string
75 | *
76 | * Returns 0 if specifier was not found in the file.
77 | * Otherwise, it returns the number of times, the
78 | * specifier was found.
79 | * Returns -1 on errors.
80 | *************************************************************/
81 | int tmParam_extractParam(struct bstrList *txtlist,
82 | const char *fltr, int type,
83 | void *value);
84 |
85 | /*************************************************************
86 | * Function searches for a specifier in a bstrList.
87 | * The string behind the specifier is then extracted
88 | * from the file and processed as an array of values
89 | * and stored in .
90 | * The values are casted to a prescribed type
91 | * type = 0: integer
92 | * type = 1: double
93 | * type = 2: string
94 | *
95 | * Returns 0 if specifier was not found in the file.
96 | * Otherwise, it returns the number of times, the
97 | * specifier was found.
98 | * Returns -1 on errors.
99 | *************************************************************/
100 | int tmParam_extractArray(struct bstrList *txtlist,
101 | const char *fltr, int type,
102 | void *value);
103 |
104 | /*************************************************************
105 | * Function to extract the node coordinates from a parameter
106 | * file
107 | *************************************************************/
108 | int tmParam_readNodeCoords(struct bstrList *txtlist,
109 | tmDouble (**xy)[2],
110 | int *n);
111 |
112 | /*************************************************************
113 | * Function to extract the exterior boundary data
114 | * from a parameter file
115 | *
116 | * @param startStr : start identifier for which to search
117 | * @param endStr : end identifier when to stop searching
118 | * @param startLine: index of line where to start
119 | * @param readAll : boolean if whole file will be read
120 | *************************************************************/
121 | int tmParam_readBdryData(struct bstrList *txtlist,
122 | char *startStr,
123 | char *endStr,
124 | int startLine,
125 | tmBool readAll,
126 | int (**edges)[2],
127 | int **edgeMarker,
128 | tmDouble **edgeRefine,
129 | int *nEdges,
130 | int *bdryMarker);
131 |
132 | /*************************************************************
133 | * Function to extract the exterior boundary data
134 | * from a parameter file
135 | *************************************************************/
136 | int tmParam_readExtBdryData(struct bstrList *txtlist,
137 | int (**edges)[2],
138 | int **edgeMarker,
139 | tmDouble **edgeRefine,
140 | int *nEdges,
141 | int *bdryMarkers);
142 |
143 | /*************************************************************
144 | * Function to extract the exterior boundary data
145 | * from a parameter file
146 | *************************************************************/
147 | int tmParam_readIntBdryData(struct bstrList *txtlist,
148 | int (***edges)[2],
149 | int ***edgeMarker,
150 | tmDouble ***edgeRefine,
151 | int **nEdges,
152 | int **bdryMarkers,
153 | int *nBdrys);
154 |
155 |
156 | #endif
157 |
--------------------------------------------------------------------------------
/src/tmesh/include/tmesh/tmQtree.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This header file is part of the tmesh library.
3 | * This code was written by Florian Setzwein in 2020,
4 | * and is covered under the MIT License
5 | * Refer to the accompanying documentation for details
6 | * on usage and license.
7 | */
8 | #ifndef TMESH_QTREE_H
9 | #define TMESH_QTREE_H
10 |
11 | #include "tmesh/tmTypedefs.h"
12 |
13 | /**********************************************************
14 | * tmQtree: Quadtree structure
15 | **********************************************************/
16 | typedef struct tmQtree {
17 |
18 | /*-------------------------------------------------------
19 | | Parent mesh properties
20 | -------------------------------------------------------*/
21 | tmMesh *mesh;
22 |
23 | /*-------------------------------------------------------
24 | | Qtree layer starts at 0
25 | -------------------------------------------------------*/
26 | tmIndex layer;
27 | tmIndex max_layer;
28 |
29 | /*-------------------------------------------------------
30 | | Maximum number of objects the Qtree can contain
31 | -------------------------------------------------------*/
32 | int max_obj;
33 | int obj_type;
34 |
35 | /*-------------------------------------------------------
36 | | Bounding box of this Qtree
37 | -------------------------------------------------------*/
38 | tmDouble xy_min[2];
39 | tmDouble xy_max[2];
40 |
41 | /*-------------------------------------------------------
42 | | Centroid of this Qtree
43 | -------------------------------------------------------*/
44 | tmDouble xy[2];
45 |
46 | /*-------------------------------------------------------
47 | | Width / height of this Qtree
48 | -------------------------------------------------------*/
49 | tmDouble dxy[2];
50 |
51 | /*-------------------------------------------------------
52 | | Objects contained in this Qtree
53 | -------------------------------------------------------*/
54 | int n_obj_tot;
55 | int n_obj;
56 | tmList *obj;
57 |
58 | /*-------------------------------------------------------
59 | | Parent Qtree and children Qtrees
60 | -------------------------------------------------------*/
61 | tmQtree *parent;
62 |
63 | tmQtree *child_NE;
64 | tmQtree *child_NW;
65 | tmQtree *child_SW;
66 | tmQtree *child_SE;
67 |
68 | /*-------------------------------------------------------
69 | | Flag if this Qtree is splitted
70 | -------------------------------------------------------*/
71 | tmBool is_splitted;
72 |
73 | } tmQtree;
74 |
75 | /**********************************************************
76 | * Function: tmQtree_create()
77 | *----------------------------------------------------------
78 | * Create a new tmQtree structure and return a pointer
79 | * to it.
80 | *----------------------------------------------------------
81 | * @param mesh: parent mesh of the new Qtree
82 | * @param obj_type: object type of this Qtree
83 | *
84 | * @return: Pointer to a new tmQtree structure
85 | **********************************************************/
86 | tmQtree *tmQtree_create(tmMesh *mesh, int obj_type);
87 |
88 | /**********************************************************
89 | * Function: tmQtree_destroy()
90 | *----------------------------------------------------------
91 | * Destroys a tmQtree structure and frees all its memory.
92 | *----------------------------------------------------------
93 | * @param *mesh: pointer to a tmQtree to destroy
94 | **********************************************************/
95 | void tmQtree_destroy(tmQtree *qtree);
96 |
97 | /**********************************************************
98 | * Function: tmQtree_init()
99 | *----------------------------------------------------------
100 | * Initialize a tmQtree structure
101 | *----------------------------------------------------------
102 | * @param qtree: tmQtree structure to initialize
103 | *
104 | **********************************************************/
105 | void tmQtree_init(tmQtree *qtree,
106 | tmQtree *parent, tmIndex layer,
107 | tmDouble xy_min[2], tmDouble xy_max[2]);
108 |
109 | /**********************************************************
110 | * Function: tmQtree_addObj()
111 | *----------------------------------------------------------
112 | * Try to add an object to the qtree
113 | *----------------------------------------------------------
114 | * @param qtree: tmQtree structure
115 | * @param obj: object to add to the qtree
116 | **********************************************************/
117 | tmBool tmQtree_addObj(tmQtree *qtree, void *obj);
118 |
119 | /**********************************************************
120 | * Function: tmQtree_remObj()
121 | *----------------------------------------------------------
122 | * Try to remove an object from the qtree
123 | *----------------------------------------------------------
124 | * @param qtree: tmQtree structure
125 | * @param obj: object to remove from the qtree
126 | **********************************************************/
127 | tmBool tmQtree_remObj(tmQtree *qtree, void *obj);
128 |
129 | /**********************************************************
130 | * Function: tmQtree_getObjNo()
131 | *----------------------------------------------------------
132 | * Return the number of objects contained in this qtree
133 | *----------------------------------------------------------
134 | * @param qtree: tmQtree structure
135 | **********************************************************/
136 | int tmQtree_getObjNo(tmQtree *qtree);
137 |
138 | /**********************************************************
139 | * Function: tmQtree_containsObj()
140 | *----------------------------------------------------------
141 | * Check if a given objects i contained within this qtree
142 | *----------------------------------------------------------
143 | * @param qtree: tmQtree structure
144 | * @param obj_type: object type of this Qtree
145 | **********************************************************/
146 | tmBool tmQtree_containsObj(tmQtree *qtree,
147 | void *obj,
148 | int mode);
149 |
150 | /**********************************************************
151 | * Function: tmQtree_getObjBbox()
152 | *----------------------------------------------------------
153 | * Return a list of objects that are contained within
154 | * a specified bounding box
155 | *----------------------------------------------------------
156 | * @param qtree: tmQtree structure to initialize
157 | * @param xy_min, xy_max: bounding box
158 | *
159 | **********************************************************/
160 | tmList *tmQtree_getObjBbox(tmQtree *qtree,
161 | tmDouble xy_min[2],
162 | tmDouble xy_max[2]);
163 |
164 | /**********************************************************
165 | * Function: tmQtree_getObjCirc()
166 | *----------------------------------------------------------
167 | * Return a list of objects that are contained within
168 | * a specified circle
169 | *----------------------------------------------------------
170 | * @param qtree: tmQtree structure to initialize
171 | * @param xy: circle centroid
172 | * @param r: circle radius
173 | *
174 | **********************************************************/
175 | tmList *tmQtree_getObjCirc(tmQtree *qtree,
176 | tmDouble xy[2],
177 | tmDouble r);
178 |
179 | /**********************************************************
180 | * Function: tmQtree_printQtree()
181 | *----------------------------------------------------------
182 | * Function to print out the qtree data
183 | *----------------------------------------------------------
184 | * @param qtree: tmQtree structure to initialize
185 | *
186 | **********************************************************/
187 | void tmQtree_printQtree(tmQtree *qtree);
188 |
189 | #endif
190 |
--------------------------------------------------------------------------------
/src/tmesh/include/tmesh/tmTri.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This header file is part of the tmesh library.
3 | * This code was written by Florian Setzwein in 2020,
4 | * and is covered under the MIT License
5 | * Refer to the accompanying documentation for details
6 | * on usage and license.
7 | */
8 | #ifndef TMESH_TMTRI_H
9 | #define TMESH_TMTRI_H
10 |
11 | #include "tmesh/tmTypedefs.h"
12 |
13 | /**********************************************************
14 | * tmTri: Triangle structure
15 | **********************************************************/
16 | typedef struct tmTri {
17 |
18 | /*-------------------------------------------------------
19 | | Parent mesh properties
20 | -------------------------------------------------------*/
21 | tmMesh *mesh;
22 |
23 | /*-------------------------------------------------------
24 | | Triangle index
25 | -------------------------------------------------------*/
26 | tmListNode *stack_pos;
27 | tmListNode *qtree_pos;
28 | tmQtree *qtree;
29 |
30 | /*-------------------------------------------------------
31 | | Triangle nodes
32 | | Aligned in counter-clockwise orientation
33 | -------------------------------------------------------*/
34 | tmNode *n1;
35 | tmNode *n2;
36 | tmNode *n3;
37 |
38 | /*-------------------------------------------------------
39 | | Position of this triangle in its nodes triangle-lists
40 | | -> Every node has a list with its adjacent triangles,
41 | | These references recover the position of this
42 | | triangle in the lists of its nodes
43 | -------------------------------------------------------*/
44 | tmListNode *n1_pos;
45 | tmListNode *n2_pos;
46 | tmListNode *n3_pos;
47 |
48 | /*-------------------------------------------------------
49 | | Triangle neighbors
50 | | Aligned in counter-clockwise orientation
51 | | t1: located opposite of n1
52 | | shares e1
53 | | t2: located opposite of n2
54 | | shares e2
55 | | t3: located pposite of n3
56 | | shares e3
57 | -------------------------------------------------------*/
58 | tmTri *t1;
59 | tmTri *t2;
60 | tmTri *t3;
61 |
62 | /*-------------------------------------------------------
63 | | Triangle edges ( only edges of the tmMesh_edgeStack )
64 | | Aligned in counter-clockwise orientation
65 | | e1: located opposite of n1
66 | | adjacent to t1
67 | | e2: located opposite of n2
68 | | adjacent to t2
69 | | e3: located pposite of n3
70 | | adjacent to t3
71 | -------------------------------------------------------*/
72 | tmEdge *e1;
73 | tmEdge *e2;
74 | tmEdge *e3;
75 |
76 | /*-------------------------------------------------------
77 | | Centroid coordinates
78 | -------------------------------------------------------*/
79 | tmDouble xy[2];
80 | tmIndex index; /* Only used for the mesh output */
81 |
82 | /*-------------------------------------------------------
83 | | Triangle properties
84 | -------------------------------------------------------*/
85 | tmDouble edgeLen[3];
86 | tmDouble area;
87 | tmDouble shapeFac;
88 | tmDouble angles[3];
89 | tmDouble minAngle;
90 | tmDouble maxAngle;
91 | tmDouble quality;
92 |
93 | /*-------------------------------------------------------
94 | | Circumcenter und circumradius
95 | -------------------------------------------------------*/
96 | tmDouble circ_xy[2];
97 | tmDouble circ_r;
98 | tmBool is_delaunay;
99 |
100 | /*-------------------------------------------------------
101 | | Buffer variables ( e.g. for sorting )
102 | -------------------------------------------------------*/
103 | tmDouble dblBuf;
104 | tmIndex indBuf;
105 |
106 | } tmTri;
107 |
108 |
109 |
110 | /**********************************************************
111 | * Function: tmTri_create()
112 | *----------------------------------------------------------
113 | * Create a new tmTri structure and return a pointer
114 | * to it.
115 | *----------------------------------------------------------
116 | * @param mesh: parent mesh of the new triangle
117 | * @param n1,n2,n3: nodes defining the triangle
118 | *
119 | * @return: Pointer to a new tmTri structure
120 | **********************************************************/
121 | tmTri *tmTri_create(tmMesh *mesh,
122 | tmNode *n1, tmNode *n2, tmNode *n3);
123 |
124 |
125 | /**********************************************************
126 | * Function: tmTri_destroy()
127 | *----------------------------------------------------------
128 | * Destroys a tmTri structure and frees all its memory.
129 | *----------------------------------------------------------
130 | * @param *mesh: pointer to a tmTri to destroy
131 | **********************************************************/
132 | void tmTri_destroy(tmTri *tri);
133 |
134 | /**********************************************************
135 | * Function: tmTri_findNbrTriFromEdge()
136 | *----------------------------------------------------------
137 | * Searches for a neighboring triangle, which is adjacent
138 | * to an edge defined by two vertices (n1, n2)
139 | * The arrangement of n1 and n2 plays no role.
140 | *----------------------------------------------------------
141 | * @param n1,n2: nodes defining an edge, for which a
142 | * triangle must be found
143 | * @param tri: triangle for which a neighbor will be found
144 | * if one has been found, it will be included
145 | * to its neighbors
146 | **********************************************************/
147 | tmTri *tmTri_findTriNeighbor(tmNode *n1,
148 | tmNode *n2,
149 | tmTri *tri);
150 |
151 | /**********************************************************
152 | * Function: tmTri_isValid()
153 | *----------------------------------------------------------
154 | * Function to check wether a provided triangle is valid
155 | *----------------------------------------------------------
156 | * @param *tri: pointer to a tmTri
157 | **********************************************************/
158 | tmBool tmTri_isValid(tmTri *tri);
159 |
160 | /**********************************************************
161 | * Function: tmTri_edgeIntersect()
162 | *----------------------------------------------------------
163 | * Function to check wether a provided triangles intersects
164 | * with an edge, defined by its vertices e1, e2
165 | *----------------------------------------------------------
166 | * @param *t1: pointer to first tmTri
167 | * @param *t2: pointer to second tmTri
168 | **********************************************************/
169 | tmBool tmTri_edgeIntersect(tmTri *t, tmNode *e1, tmNode *e2);
170 |
171 | /**********************************************************
172 | * Function: tmTri_triIntersectn()
173 | *----------------------------------------------------------
174 | * Function to check wether two provided triangles intersect
175 | *----------------------------------------------------------
176 | * @param *t1: pointer to first tmTri
177 | * @param *t2: pointer to second tmTri
178 | **********************************************************/
179 | tmBool tmTri_triIntersect(tmTri *t1, tmTri *t2);
180 |
181 | /**********************************************************
182 | * Function: tmTri_nodeIntersect()
183 | *----------------------------------------------------------
184 | * Function to check wether a provided triangles intersects
185 | * with a node
186 | *----------------------------------------------------------
187 | * @param *t: pointer to tmTri
188 | * @param *n: pointer to tmNode
189 | **********************************************************/
190 | tmBool tmTri_nodeIntersect(tmTri *t, tmNode *n);
191 |
192 | #endif
193 |
--------------------------------------------------------------------------------
/src/tmesh/include/tmesh/tmTypedefs.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This header file is part of the tmesh library.
3 | * This code was written by Florian Setzwein in 2020,
4 | * and is covered under the MIT License
5 | * Refer to the accompanying documentation for details
6 | * on usage and license.
7 | */
8 | #ifndef TMESH_TMTYPEDEFS_H
9 | #define TMESH_TMTYPEDEFS_H
10 |
11 | #include
12 | #include
13 | #define _USE_MATH_DEFINES
14 | #include
15 |
16 | #include "tmesh/dbg.h"
17 | #include "tmesh/tmList.h"
18 |
19 | /***********************************************************
20 | * Flag to use double precision -> undefine to use float
21 | ***********************************************************/
22 | #define TM_USE_DOUBLE
23 |
24 | /***********************************************************
25 | * Own type definitions in order to allow to switch from
26 | * switch to short and from double to long in case of
27 | * special memory requirements
28 | ***********************************************************/
29 | #define tmDouble double
30 | #define tmIndex int
31 | #define tmBool int
32 | #define TRUE 1
33 | #define FALSE 0
34 |
35 | /***********************************************************
36 | * Basic structure labels
37 | ***********************************************************/
38 | #define TM_NODE 0
39 | #define TM_EDGE 1
40 | #define TM_TRI 2
41 |
42 | /***********************************************************
43 | * Basic structure typedefs
44 | ***********************************************************/
45 | typedef struct tmNode tmNode;
46 | typedef struct tmEdge tmEdge;
47 | typedef struct tmTri tmTri;
48 | typedef struct tmBdry tmBdry;
49 | typedef struct tmFront tmFront;
50 | typedef struct tmQtree tmQtree;
51 | typedef struct tmMesh tmMesh;
52 |
53 | /***********************************************************
54 | * Function pointers
55 | ***********************************************************/
56 | typedef tmDouble (*tmSizeFun) (tmMesh *mesh, tmDouble xy[2]);
57 | typedef tmDouble (*tmSizeFunUser) (tmDouble xy[2]);
58 |
59 |
60 | /***********************************************************
61 | * Debugging Layers
62 | * 0 -> No output
63 | ***********************************************************/
64 | #define TM_DEBUG 0
65 |
66 | #ifdef TM_DEBUG
67 | #define tmPrint(M, ...) fprintf(stdout, "> " M "\n",\
68 | ##__VA_ARGS__)
69 | #else
70 | #define tmPrint(M, ...)
71 | #endif
72 |
73 |
74 | /***********************************************************
75 | * Constants used in code
76 | ***********************************************************/
77 | #define PI_D 3.1415926535897932384626433832795
78 | #define TM_MIN_SIZE 1.0E-8
79 | #define TM_QTREE_MAX_LAYER 100
80 |
81 |
82 | /***********************************************************
83 | * MESHING PARAMETERS
84 | ***********************************************************/
85 | #define TM_NEW_NODE_DIST_FAC ( 1.05 ) // 1.15
86 | #define TM_NODE_EDGE_DIST_FAC ( 0.40 )
87 | #define TM_TRI_RANGE_FAC ( 2.35 )
88 | #define TM_BDRY_REFINE_FAC ( 1.00 )
89 | #define TM_FRONT_REFINE_FAC ( 1.00 )
90 | #define TM_NODE_NBR_DIST_FAC ( 1.00 )
91 | #define TM_TRI_NODE_RANGE_FAC ( 1.50 )
92 | #define TM_TRI_MIN_ANGLE ( ( 15.0*PI_D)/180.0 )
93 | #define TM_TRI_MAX_ANGLE ( (165.0*PI_D)/180.0 )
94 | #define TM_TRI_MIN_QUALITY ( 0.04 )
95 | #define TM_SIZEFUN_SLOPE ( 1.0 )
96 |
97 | /***********************************************************
98 | * Minimum and maximum allowed coordinates
99 | ***********************************************************/
100 | #define TM_X_MIN -1.0E7
101 | #define TM_Y_MIN -1.0E7
102 | #define TM_X_MAX 1.0E7
103 | #define TM_Y_MAX 1.0E7
104 |
105 | #define SMALL 1.0E-13
106 |
107 | /***********************************************************
108 | * Helper functions
109 | ***********************************************************/
110 | #ifndef SQR
111 | #define SQR(x) ( (x) * (x) )
112 | #endif
113 |
114 | #ifndef MAX
115 | #define MAX(a, b) ( (a) > (b) ? (a) : (b) )
116 | #endif
117 |
118 | #ifndef MIN
119 | #define MIN(a, b) ( (a) < (b) ? (a) : (b) )
120 | #endif
121 |
122 | #ifndef MAX0
123 | #define MAX0(a) ( (a) > 0 ? (a) : 0 )
124 | #endif
125 |
126 | #ifndef MIN0
127 | #define MIN0(a) ( (a) < 0 ? (a) : 0 )
128 | #endif
129 |
130 | #ifndef ABS
131 | #define ABS(a) ( (a) < 0 ? -1 * (a) : (a) )
132 | #endif
133 |
134 | #ifndef EQ
135 | #define EQ(a, b) ( ABS((a)- (b)) < SMALL ? 1 : 0 )
136 | #endif
137 |
138 |
139 | /***********************************************************
140 | * Geometric functions
141 | ***********************************************************/
142 | #define IN_ON_BBOX(n, min, max) \
143 | ( ( (n)[0] >= (min)[0] ) \
144 | && ( (n)[1] >= (min)[1] ) \
145 | && ( (n)[0] <= (max)[0] ) \
146 | && ( (n)[1] <= (max)[1] ) )
147 |
148 | #define IN_BBOX(n, min, max) \
149 | ( ( (n)[0] > (min)[0] ) \
150 | && ( (n)[1] > (min)[1] ) \
151 | && ( (n)[0] < (max)[0] ) \
152 | && ( (n)[1] < (max)[1] ) )
153 |
154 | #define ON_BBOX(n, min, max) \
155 | ( ( EQ( (n)[0], (min)[0] ) && ( (n)[1] >= (min)[1] ) && ( (n)[1] <= (max)[1] ) ) \
156 | || ( EQ( (n)[0], (max)[0] ) && ( (n)[1] >= (min)[1] ) && ( (n)[1] <= (max)[1] ) ) \
157 | || ( EQ( (n)[1], (min)[1] ) && ( (n)[0] >= (min)[0] ) && ( (n)[0] <= (max)[0] ) ) \
158 | || ( EQ( (n)[1], (max)[1] ) && ( (n)[0] >= (min)[0] ) && ( (n)[0] <= (max)[0] ) ) )
159 |
160 | #define BBOX_OVERLAP(pqmin, pqmax, rsmin, rsmax) \
161 | ( ( (pqmin)[0] <= (rsmax)[0] ) \
162 | && ( (rsmin)[0] <= (pqmax)[0] ) \
163 | && ( (pqmin)[1] <= (rsmax)[1] ) \
164 | && ( (rsmin)[1] <= (pqmax)[1] ) )
165 |
166 |
167 | /*----------------------------------------------------------
168 | | check the orientation of a node tuple (p,q,r)
169 | ----------------------------------------------------------*/
170 | static inline int ORIENTATION(tmDouble p[2],
171 | tmDouble q[2],
172 | tmDouble r[2])
173 | {
174 | tmDouble area2 = ( ( p[0] - r[0] ) * ( q[1] - r[1] )
175 | - ( q[0] - r[0] ) * ( p[1] - r[1] ) );
176 |
177 | /* Colinearity of all nodes */
178 | if ( (area2 * area2) < SMALL )
179 | return 0;
180 |
181 | /* Counter clockwise orienation */
182 | if ( area2 > 0.0 )
183 | return 1;
184 |
185 | return 2;
186 | }
187 |
188 | /*----------------------------------------------------------
189 | | check if node r is located to the left of (p,q)
190 | ----------------------------------------------------------*/
191 | static inline tmBool IS_LEFT(tmDouble p[2],
192 | tmDouble q[2],
193 | tmDouble r[2])
194 | {
195 | if ( ORIENTATION(p, q, r) == 1 )
196 | return TRUE;
197 | return FALSE;
198 | }
199 |
200 | /*----------------------------------------------------------
201 | | check if node r is located to the left of (p,q) or on it
202 | ----------------------------------------------------------*/
203 | static inline tmBool IS_LEFTON(tmDouble p[2],
204 | tmDouble q[2],
205 | tmDouble r[2])
206 | {
207 | if ( ORIENTATION(p, q, r) == 2 )
208 | return FALSE;
209 | return TRUE;
210 | }
211 |
212 | /*----------------------------------------------------------
213 | | check if node r is located to the right of (p,q)
214 | ----------------------------------------------------------*/
215 | static inline tmBool IS_RIGHT(tmDouble p[2],
216 | tmDouble q[2],
217 | tmDouble r[2])
218 | {
219 | if ( ORIENTATION(p, q, r) == 2 )
220 | return TRUE;
221 | return FALSE;
222 | }
223 |
224 | /*----------------------------------------------------------
225 | | check if node r is located to the right of (p,q) or on it
226 | ----------------------------------------------------------*/
227 | static inline tmBool IS_RIGHTON(tmDouble p[2],
228 | tmDouble q[2],
229 | tmDouble r[2])
230 | {
231 | if ( ORIENTATION(p, q, r) == 1 )
232 | return FALSE;
233 | return TRUE;
234 | }
235 |
236 | /*----------------------------------------------------------
237 | | Function returns the squared normal distance between an
238 | | edge and a node.
239 | | The edge is defined through its vertices (v,w)
240 | | The node is defined through its coordinates p
241 | |
242 | | Source:
243 | | https://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment
244 | ----------------------------------------------------------*/
245 | static inline tmDouble EDGE_NODE_DIST2(tmDouble v[2],
246 | tmDouble w[2],
247 | tmDouble p[2])
248 | {
249 | const tmDouble dx_e = w[0]-v[0];
250 | const tmDouble dy_e = w[1]-v[1];
251 | const tmDouble l2 = dx_e*dx_e + dy_e*dy_e;
252 |
253 | const tmDouble dotP = ( (p[0]-v[0]) * dx_e
254 | + (p[1]-v[1]) * dy_e ) / l2;
255 |
256 | const tmDouble t = MAX(0.0, MIN(1.0, dotP));
257 |
258 | const tmDouble proj_x = v[0] + t * dx_e;
259 | const tmDouble proj_y = v[1] + t * dy_e;
260 |
261 | const tmDouble dx = proj_x - p[0];
262 | const tmDouble dy = proj_y - p[1];
263 |
264 | const tmDouble dist2 = dx*dx + dy*dy;
265 |
266 | return dist2;
267 | }
268 |
269 | /*----------------------------------------------------------
270 | | Check if an object is contained in a provided list
271 | ----------------------------------------------------------*/
272 | static inline tmBool OBJ_IN_LIST(void *obj, tmList *list)
273 | {
274 | tmListNode *cur;
275 | for (cur = list->first; cur != NULL; cur = cur->next)
276 | if ( cur->value == obj )
277 | return TRUE;
278 |
279 | return FALSE;
280 | error:
281 | return -1;
282 | }
283 |
284 | /*----------------------------------------------------------
285 | | Check if r lies within a segment (p,q)
286 | ----------------------------------------------------------*/
287 | static inline tmBool IN_SEGMENT(tmDouble p[2],
288 | tmDouble q[2],
289 | tmDouble r[2])
290 | {
291 | if ( ORIENTATION(p, q, r) != 0 )
292 | return FALSE;
293 |
294 | tmDouble bbox_min[2] = { MIN(p[0], q[0]),
295 | MIN(p[1], q[1]) };
296 | tmDouble bbox_max[2] = { MAX(p[0], q[0]),
297 | MAX(p[1], q[1]) };
298 |
299 | const tmDouble dx_e = q[0]-p[0];
300 | const tmDouble dy_e = q[1]-p[1];
301 | const tmDouble l2 = dx_e*dx_e + dy_e*dy_e;
302 | const tmDouble t = ( (r[0]-p[0]) * dx_e
303 | + (r[1]-p[1]) * dy_e ) / l2;
304 |
305 | if ( t > 0.0 && t < 1.0 )
306 | return TRUE;
307 |
308 | return FALSE;
309 | }
310 |
311 | /*----------------------------------------------------------
312 | | Check if r lies within a segment (p,q) or on its endpoints
313 | ----------------------------------------------------------*/
314 | static inline tmBool IN_ON_SEGMENT(tmDouble p[2],
315 | tmDouble q[2],
316 | tmDouble r[2])
317 | {
318 | if ( ORIENTATION(p, q, r) != 0 )
319 | return FALSE;
320 |
321 | tmDouble bbox_min[2] = { MIN(p[0], q[0]),
322 | MIN(p[1], q[1]) };
323 | tmDouble bbox_max[2] = { MAX(p[0], q[0]),
324 | MAX(p[1], q[1]) };
325 |
326 | const tmDouble dx_e = q[0]-p[0];
327 | const tmDouble dy_e = q[1]-p[1];
328 | const tmDouble l2 = dx_e*dx_e + dy_e*dy_e;
329 | const tmDouble t = ( (r[0]-p[0]) * dx_e
330 | + (r[1]-p[1]) * dy_e ) / l2;
331 |
332 | if ( t >= 0.0 && t <= 1.0 )
333 | return TRUE;
334 |
335 | return FALSE;
336 | }
337 |
338 | /*----------------------------------------------------------
339 | | Check if two line segments (p1,q1), (p2,q2) are crossing
340 | |
341 | | * Returns True, if segments intersect at any point but
342 | | their endings
343 | | * Returns True, if one line contains a part of the other
344 | | * Returns False, if both lines share both end points
345 | | * Returns False in all other cases
346 | |
347 | | -> Used for triangle edge intersection
348 | ----------------------------------------------------------*/
349 | static inline tmBool INTERSECTION_IN_LINES(tmDouble p1[2],
350 | tmDouble q1[2],
351 | tmDouble p2[2],
352 | tmDouble q2[2])
353 | {
354 | int o1 = ORIENTATION(p1, q1, p2);
355 | int o2 = ORIENTATION(p1, q1, q2);
356 | int o3 = ORIENTATION(p2, q2, p1);
357 | int o4 = ORIENTATION(p2, q2, q1);
358 |
359 | if ( ( (o1 == 1 && o2 == 2) || (o1 == 2 && o2 == 1) )
360 | && ( (o3 == 1 && o4 == 2) || (o3 == 2 && o4 == 1) ) )
361 | {
362 | return TRUE;
363 | }
364 |
365 | /* (p1, q1) and p2 are colinear and p2 lies on segment (p1, q1) */
366 | if ( (o1 == 0) && ( IN_SEGMENT(p1, q1, p2) == TRUE ) )
367 | return TRUE;
368 |
369 | /* (p1, q1) and q2 are colinear and q2 lies on segment (p1, q1) */
370 | if ( (o2 == 0) && ( IN_SEGMENT(p1, q1, q2) == TRUE ) )
371 | return TRUE;
372 |
373 | /* (p2, q2) and p1 are colinear and p1 lies on segment (p2, q2) */
374 | if ( (o3 == 0) && ( IN_SEGMENT(p2, q2, p1) == TRUE ) )
375 | return TRUE;
376 |
377 | /* (p2, q2) and q1 are colinear and q1 lies on segment (p2, q2) */
378 | if ( (o4 == 0) && ( IN_SEGMENT(p2, q2, q1) == TRUE ))
379 | return TRUE;
380 |
381 | return FALSE;
382 |
383 | }
384 |
385 |
386 | #endif /* TMESH_TMTYPEDEFS_H */
387 |
--------------------------------------------------------------------------------
/src/tmesh/src/main.c:
--------------------------------------------------------------------------------
1 | #include "tmesh/tmParam.h"
2 | #include "tmesh/tmNode.h"
3 | #include "tmesh/tmEdge.h"
4 | #include "tmesh/tmTri.h"
5 | #include "tmesh/tmBdry.h"
6 | #include "tmesh/tmMesh.h"
7 | #include "tmesh/tmQtree.h"
8 | #include "tmesh/tmFront.h"
9 | #include "tmesh/tmList.h"
10 |
11 | #include "tmesh/tinyexpr.h"
12 |
13 | #include
14 | #include
15 | #define _USE_MATH_DEFINES
16 | #include
17 | #include
18 |
19 |
20 | tmDouble x, y;
21 | te_variable vars[] = {{"x", &x}, {"y", &y}};
22 | te_expr *expr;
23 |
24 | static inline tmDouble sizeFun( tmDouble xy[2] )
25 | {
26 | x = xy[0];
27 | y = xy[1];
28 | return te_eval(expr);
29 | }
30 |
31 |
32 | /*************************************************************
33 | *
34 | *************************************************************/
35 | int main(int argc, char *argv[])
36 | {
37 | if (argc < 2)
38 | {
39 | tmPrint("tmesh ");
40 | return 0;
41 | }
42 |
43 | char *input = argv[1];
44 | tmParam *file;
45 |
46 | int i,j;
47 |
48 | tmSizeFunUser sizeFunUser;
49 |
50 | tmDouble globSize;
51 | tmDouble *globBbox = NULL;
52 | int qtreeSize;
53 | bstring sizeFunExpr;
54 |
55 | tmDouble (*nodes)[2] = NULL;
56 | int nNodes;
57 |
58 | int (*extBdryEdges)[2] = NULL;
59 | int *extBdryEdgeMarker = NULL;
60 | tmDouble *extBdryRefinement = NULL;
61 | int nExtBdryEdges;
62 | int extBdryMarker;
63 |
64 | int (**intrEdges)[2] = NULL;
65 | int **intrEdgeMarkers = NULL;
66 | tmDouble **intrEdgeRefinements = NULL;
67 | int *nIntrEdges = NULL;
68 | int *intrBdryMarkers = NULL;
69 | int nIntrBdrys = 0;
70 |
71 |
72 | /*----------------------------------------------------------
73 | | Load parameter file and clear comments
74 | ----------------------------------------------------------*/
75 | struct bstrList *buf;
76 |
77 | file = tmParam_create( input );
78 | buf = tmParam_removeComments(file->txtlist, "#");
79 | bstrListDestroy(file->txtlist);
80 | file->txtlist = buf;
81 |
82 | /*----------------------------------------------------------
83 | | Extract mandatory meshing parameters
84 | ----------------------------------------------------------*/
85 | check( tmParam_extractParam(file->txtlist,
86 | "Global element size:", 1, &globSize) != 0,
87 | "Missing parameter ");
88 |
89 | check( tmParam_extractArray(file->txtlist,
90 | "Mesh bounding box:", 1, &globBbox) != 0,
91 | "Missing parameter ");
92 |
93 | /*----------------------------------------------------------
94 | | Extract optional meshing parameters
95 | ----------------------------------------------------------*/
96 | if ( tmParam_extractParam(file->txtlist,
97 | "Number of quadtree elements:", 0, &qtreeSize) == 0 )
98 | {
99 | qtreeSize = 100;
100 | }
101 |
102 | if ( tmParam_extractParam(file->txtlist,
103 | "Size function:", 2, &sizeFunExpr) != 0 )
104 | {
105 | int err;
106 | expr = te_compile(sizeFunExpr->data, vars, 2, &err);
107 | check(err == 0, "Wrong size function definition");
108 | tmPrint("SIZE FUNCTION: %s", sizeFunExpr->data);
109 | sizeFunUser = sizeFun;
110 | }
111 | else {
112 | sizeFunExpr = NULL;
113 | sizeFunUser = NULL;
114 | }
115 |
116 | /*----------------------------------------------------------
117 | | Extract node definitions
118 | ----------------------------------------------------------*/
119 | tmParam_readNodeCoords(file->txtlist, &nodes, &nNodes);
120 |
121 | /*----------------------------------------------------------
122 | | Extract exterior boundary definition
123 | ----------------------------------------------------------*/
124 | tmParam_readExtBdryData(file->txtlist,
125 | &extBdryEdges,
126 | &extBdryEdgeMarker,
127 | &extBdryRefinement,
128 | &nExtBdryEdges,
129 | &extBdryMarker);
130 |
131 | /*----------------------------------------------------------
132 | | Extract interior boundary definitions
133 | ----------------------------------------------------------*/
134 | tmParam_readIntBdryData(file->txtlist,
135 | &intrEdges,
136 | &intrEdgeMarkers,
137 | &intrEdgeRefinements,
138 | &nIntrEdges,
139 | &intrBdryMarkers,
140 | &nIntrBdrys);
141 |
142 | /*----------------------------------------------------------
143 | | Build the mesh
144 | ----------------------------------------------------------*/
145 | tmDouble xyMin[2] = { globBbox[0], globBbox[1] };
146 | tmDouble xyMax[2] = { globBbox[2], globBbox[3] };
147 |
148 | tmMesh *mesh = tmMesh_create(xyMin, xyMax,
149 | qtreeSize,
150 | globSize,
151 | sizeFunUser);
152 |
153 |
154 | /*----------------------------------------------------------
155 | | Add nodes to the mesh
156 | ----------------------------------------------------------*/
157 | tmNode **nodes_ptr = calloc(nNodes, sizeof(tmNode*));
158 | tmNode *newNode;
159 |
160 | for (i = 0; i < nNodes; i++)
161 | {
162 | newNode = tmNode_create(mesh, nodes[i]);
163 | nodes_ptr[i] = newNode;
164 | }
165 |
166 | /*----------------------------------------------------------
167 | | Add exterior boundary to the mesh
168 | ----------------------------------------------------------*/
169 | tmEdge *bdryEdge;
170 | tmBdry *bdry_ext = tmMesh_addBdry(mesh,
171 | FALSE,
172 | extBdryMarker);
173 |
174 | for (i = 0; i < nExtBdryEdges; i++)
175 | {
176 | int i0 = extBdryEdges[i][0];
177 | int i1 = extBdryEdges[i][1];
178 |
179 | check( i0 < nNodes && i1 < nNodes,
180 | "Defined nodes do not fit to exterior boundary definition.");
181 |
182 | bdryEdge = tmBdry_edgeCreate(bdry_ext,
183 | nodes_ptr[i0],
184 | nodes_ptr[i1],
185 | extBdryEdgeMarker[i],
186 | extBdryRefinement[i]);
187 | }
188 |
189 |
190 | /*----------------------------------------------------------
191 | | Add interior boundaries to the mesh
192 | ----------------------------------------------------------*/
193 | tmBdry *bdry_int;
194 | for (j = 0; j < nIntrBdrys; j++)
195 | {
196 | bdry_int = tmMesh_addBdry(mesh,
197 | TRUE,
198 | intrBdryMarkers[j]);
199 |
200 | for (i = 0; i < nIntrEdges[j]; i++)
201 | {
202 | int i0 = intrEdges[j][i][0];
203 | int i1 = intrEdges[j][i][1];
204 |
205 | check( i0 < nNodes && i1 < nNodes,
206 | "Defined nodes do not fit to interior boundary with marker %d.",
207 | intrBdryMarkers[j]);
208 |
209 | bdryEdge = tmBdry_edgeCreate(bdry_int,
210 | nodes_ptr[i0],
211 | nodes_ptr[i1],
212 | intrEdgeMarkers[j][i],
213 | intrEdgeRefinements[j][i]);
214 | }
215 | }
216 |
217 | /*--------------------------------------------------------
218 | | Create mesh
219 | --------------------------------------------------------*/
220 | clock_t tic_1 = clock();
221 | tmMesh_ADFMeshing(mesh);
222 | clock_t tic_2 = clock();
223 |
224 | /*--------------------------------------------------------
225 | | Print the mesh data
226 | --------------------------------------------------------*/
227 | //tmMesh_printMesh(mesh);
228 | tmMesh_printMeshIncomflow(mesh);
229 |
230 |
231 | tmPrint("----------------------------------------------\n");
232 | tmPrint("TMesh finished\n");
233 | tmPrint("----------------------------------------------\n");
234 | tmPrint("Number of elements: %d\n", mesh->no_tris);
235 | tmPrint("Meshing time : %e sec\n",
236 | (double) (tic_2 - tic_1) / CLOCKS_PER_SEC );
237 | tmPrint("----------------------------------------------\n");
238 |
239 | tmMesh_destroy(mesh);
240 |
241 |
242 |
243 | te_free(expr);
244 | free(globBbox);
245 | bdestroy(sizeFunExpr);
246 |
247 | free(nodes);
248 | free(nodes_ptr);
249 |
250 | free(extBdryEdges);
251 | free(extBdryEdgeMarker);
252 | free(extBdryRefinement);
253 |
254 | for (i = 0; i < nIntrBdrys; i++)
255 | {
256 | free(intrEdges[i]);
257 | free(intrEdgeMarkers[i]);
258 | free(intrEdgeRefinements[i]);
259 | }
260 | free(intrEdges);
261 | free(intrEdgeMarkers);
262 | free(intrEdgeRefinements);
263 | free(nIntrEdges);
264 | free(intrBdryMarkers);
265 |
266 | tmParam_destroy( file );
267 |
268 | return 0;
269 |
270 |
271 |
272 | error:
273 |
274 | te_free(expr);
275 | free(globBbox);
276 | bdestroy(sizeFunExpr);
277 |
278 | free(nodes);
279 |
280 | free(extBdryEdges);
281 | free(extBdryEdgeMarker);
282 | free(extBdryRefinement);
283 |
284 | for (i = 0; i < nIntrBdrys; i++)
285 | {
286 | free(intrEdges[i]);
287 | free(intrEdgeMarkers[i]);
288 | free(intrEdgeRefinements[i]);
289 | }
290 | free(intrEdges);
291 | free(intrEdgeMarkers);
292 | free(intrEdgeRefinements);
293 | free(nIntrEdges);
294 | free(intrBdryMarkers);
295 |
296 | tmParam_destroy( file );
297 |
298 | return 1;
299 |
300 | }
301 |
--------------------------------------------------------------------------------
/src/tmesh/src/tmList.c:
--------------------------------------------------------------------------------
1 | /*
2 | * This source file is part of the tmesh library.
3 | * This code was written by Florian Setzwein in 2020,
4 | * and is covered under the MIT License
5 | * Refer to the accompanying documentation for details
6 | * on usage and license.
7 | *
8 | * Most code in this file has been used from Zed Shaws Book
9 | * "Learn C the hard way"
10 | */
11 | #include
12 | #include "tmesh/tmList.h"
13 | #include "tmesh/dbg.h"
14 |
15 |
16 | /**************************************************************
17 | * This function creates a new list structure
18 | **************************************************************/
19 | tmList *tmList_create()
20 | {
21 | return calloc(1, sizeof(tmList));
22 | }
23 |
24 | /**************************************************************
25 | * This function frees the memory of all tmListNodes of a given
26 | * list structure
27 | **************************************************************/
28 | void tmList_destroy(tmList *list)
29 | {
30 | TMLIST_FOREACH(list, first, next, cur) {
31 | if (cur->prev) {
32 | free(cur->prev);
33 | }
34 | }
35 | free(list->last);
36 | free(list);
37 | }
38 |
39 | /**************************************************************
40 | * This function frees all memory of the data that is stored
41 | * in a given list structure
42 | **************************************************************/
43 | void tmList_clear(tmList *list)
44 | {
45 | TMLIST_FOREACH(list, first, next, cur) {
46 | free(cur->value);
47 | }
48 | }
49 |
50 | /**************************************************************
51 | * This function frees all memory of a list structure
52 | **************************************************************/
53 | void tmList_clear_destroy(tmList *list)
54 | {
55 | tmList_clear(list);
56 | tmList_destroy(list);
57 | }
58 |
59 | /**************************************************************
60 | * Push a new list node to the end of a list structure
61 | **************************************************************/
62 | void tmList_push(tmList *list, void *value)
63 | {
64 | tmListNode *node = calloc(1, sizeof(tmListNode));
65 | check_mem(node);
66 |
67 | node->value = value;
68 |
69 | if (list->last == NULL) {
70 | list->first = node;
71 | list->last = node;
72 | }
73 | else {
74 | list->last->next = node;
75 | node->prev = list->last;
76 | list->last = node;
77 | }
78 |
79 | list->count++;
80 |
81 | error:
82 | return;
83 | }
84 |
85 | /**************************************************************
86 | * Remove the last node from a list structure
87 | **************************************************************/
88 | void *tmList_pop(tmList *list)
89 | {
90 | tmListNode *node = list->last;
91 | return node != NULL ? tmList_remove(list, node) : NULL;
92 | }
93 |
94 | /**************************************************************
95 | * Push a new list node to the beginning of a list structure
96 | **************************************************************/
97 | void tmList_unshift(tmList *list, void *value)
98 | {
99 | tmListNode *node = calloc(1, sizeof(tmListNode));
100 | check_mem(node);
101 |
102 | node->value = value;
103 |
104 | if (list->first == NULL) {
105 | list->first = node;
106 | list->last = node;
107 | }
108 | else {
109 | node->next = list->first;
110 | list->first->prev = node;
111 | list->first = node;
112 | }
113 |
114 | list->count++;
115 |
116 | error:
117 | return;
118 | }
119 |
120 | /**************************************************************
121 | * Remove the first node from a list structure
122 | **************************************************************/
123 | void *tmList_shift(tmList *list)
124 | {
125 | tmListNode *node = list->first;
126 | return node != NULL ? tmList_remove(list, node) : NULL;
127 | }
128 |
129 | /**************************************************************
130 | * Remove a specific node from a list structure
131 | **************************************************************/
132 | void *tmList_remove(tmList *list, tmListNode *node)
133 | {
134 | void *result = NULL;
135 |
136 | check(list->first && list->last, "tmList is empty.");
137 | check(node, "node can't be NULL.");
138 |
139 | if (node == list->first && node == list->last) {
140 | list->first = NULL;
141 | list->last = NULL;
142 | }
143 | else if (node == list->first) {
144 | list->first = node->next;
145 | check(list->first != NULL, "Invalid list, somehow got a first that is NULL.");
146 | list->first->prev = NULL;
147 | }
148 | else if (node == list->last) {
149 | list->last = node->prev;
150 | check(list->last != NULL, "Invalid list, somehow got a last that is NULL.");
151 | list->last->next = NULL;
152 | }
153 | else {
154 | tmListNode *after = node->next;
155 | tmListNode *before = node->prev;
156 |
157 | after->prev = before;
158 | before->next = after;
159 | }
160 |
161 | list->count--;
162 | result = node->value;
163 | free(node);
164 |
165 | error:
166 | return result;
167 | }
168 |
169 | /**************************************************************
170 | * Appends to the end of
171 | **************************************************************/
172 | void *tmList_join(tmList *list1, tmList *list2)
173 | {
174 | check(list1->first || list2->first, "Both lists are empty.");
175 |
176 | if (list1->first == NULL) {
177 | list1->first = list2->first;
178 | list1->last = list2->last;
179 | list1->count = list2->count;
180 |
181 | }
182 | else {
183 | list1->last->next = list2->first;
184 | list2->first->prev = list1->last;
185 | list1->last = list2->last;
186 | list1->count += list2->count;
187 |
188 | }
189 |
190 | list2->count = 0;
191 | list2->first = NULL;
192 | list2->last = NULL;
193 |
194 | tmList_destroy(list2);
195 |
196 | error:
197 | return NULL;
198 | }
199 |
200 |
201 | /*************************************************************
202 | * Splits a list at a specified index of the list
203 | *************************************************************/
204 | tmList *tmList_split(tmList *list1, int index)
205 | {
206 | if (index == 0)
207 | return list1;
208 |
209 | if (list1->count <= 1)
210 | return list1;
211 |
212 | if (index >= list1->count || index < 0)
213 | return list1;
214 |
215 | tmListNode *node = list1->first;
216 |
217 | int i = 0;
218 | while (i < index)
219 | {
220 | i++;
221 | node = node->next;
222 | }
223 |
224 | tmList *list2 = tmList_create();
225 | list2->first = node;
226 | list2->last = list1->last;
227 |
228 | list1->last = node->prev;
229 |
230 | node->prev->next = NULL;
231 | node->prev = NULL;
232 |
233 | list2->count = list1->count - i;
234 | list1->count = i;
235 |
236 | return list2;
237 |
238 | }
239 |
240 |
241 |
242 |
243 | /*************************************************************
244 | * Function for swapping the values of two nodes in a
245 | * list structure
246 | *************************************************************/
247 | static inline void tmListNode_swap(tmListNode *a, tmListNode *b);
248 |
249 | /*************************************************************
250 | * Function for merging two lists
251 | *************************************************************/
252 | static inline tmList *tmList_merge(tmList *left, tmList *right,
253 | tmList_compare cmp);
254 |
255 |
256 |
257 | /*************************************************************
258 | * Function for swapping the values of two nodes in a
259 | * list structure
260 | *************************************************************/
261 | static inline void tmListNode_swap(tmListNode *a, tmListNode *b)
262 | {
263 | void *temp = a->value;
264 | a->value = b->value;
265 | b->value = temp;
266 | }
267 |
268 | /*************************************************************
269 | * Function for merging two lists
270 | *************************************************************/
271 | static inline tmList *tmList_merge(tmList *left, tmList *right,
272 | tmList_compare cmp)
273 | {
274 | tmList *result = tmList_create();
275 | void *val = NULL;
276 |
277 | while (tmList_count(left) > 0 || tmList_count(right) > 0) {
278 | if (tmList_count(left) > 0 && tmList_count(right) > 0) {
279 | if (cmp(tmList_first(left), tmList_first(right)) <= 0) {
280 | val = tmList_shift(left);
281 | }
282 | else {
283 | val = tmList_shift(right);
284 | }
285 | tmList_push(result, val);
286 | }
287 | else if (tmList_count(left) > 0) {
288 | val = tmList_shift(left);
289 | tmList_push(result, val);
290 | }
291 | else if (tmList_count(right) > 0) {
292 | val = tmList_shift(right);
293 | tmList_push(result, val);
294 | }
295 | }
296 |
297 | return result;
298 |
299 | }
300 |
301 | /*************************************************************
302 | * Bubble sort algorithm
303 | *************************************************************/
304 | int tmList_bubble_sort(tmList *list, tmList_compare cmp)
305 | {
306 | int sorted = 1;
307 |
308 | if (tmList_count(list) <= 1) {
309 | return 0; // Already sorted
310 | }
311 |
312 | do {
313 | sorted = 1;
314 | TMLIST_FOREACH(list, first, next, cur) {
315 | if (cur->next) {
316 | if (cmp(cur->value, cur->next->value) > 0) {
317 | tmListNode_swap(cur, cur->next);
318 | sorted = 0;
319 | }
320 | }
321 | }
322 | } while (!sorted);
323 |
324 | return 0;
325 | }
326 |
327 |
328 | /*************************************************************
329 | * Merge sort algorithm
330 | *************************************************************/
331 | tmList *tmList_merge_sort(tmList *list, tmList_compare cmp)
332 | {
333 | tmList *result = NULL;
334 |
335 | if (tmList_count(list) <= 1) {
336 | return list;
337 | }
338 |
339 | tmList *left = tmList_create();
340 | tmList *right = tmList_create();
341 | int middle = tmList_count(list) / 2;
342 |
343 | TMLIST_FOREACH(list, first, next, cur) {
344 | if (middle > 0) {
345 | tmList_push(left, cur->value);
346 | }
347 | else {
348 | tmList_push(right, cur->value);
349 | }
350 |
351 | middle--;
352 | }
353 |
354 | tmList *sort_left = tmList_merge_sort(left, cmp);
355 | tmList *sort_right = tmList_merge_sort(right, cmp);
356 |
357 | if (sort_left != left)
358 | tmList_destroy(left);
359 | if (sort_right != right)
360 | tmList_destroy(right);
361 |
362 | result = tmList_merge(sort_left, sort_right, cmp);
363 |
364 | tmList_destroy(sort_left);
365 | tmList_destroy(sort_right);
366 |
367 | return result;
368 |
369 | }
370 |
--------------------------------------------------------------------------------
/src/tmesh/test/geom_tests.c:
--------------------------------------------------------------------------------
1 | #include "tmesh/tmTypedefs.h"
2 |
3 | #include "tmesh/minunit.h"
4 | #include "tmesh/dbg.h"
5 |
6 | #include
7 | #include
8 |
9 | /*************************************************************
10 | * Unit test function for geometric functions
11 | *************************************************************/
12 | char *test_geometric_functions()
13 | {
14 | tmDouble bbox_min[2] = { -1.23, -2.34 };
15 | tmDouble bbox_max[2] = { 2.34, 1.23 };
16 |
17 | tmDouble xy_1[2] = { 0.1, 0.1 };
18 | tmDouble xy_2[2] = {-5.1, 0.1 };
19 | tmDouble xy_3[2] = { 2.34,-1.1 };
20 |
21 | tmDouble bbox_1_min[2] = { 1.0, -3.0 };
22 | tmDouble bbox_1_max[2] = { 4.0, 1.1 };
23 |
24 | tmDouble bbox_2_min[2] = { 4.0, 1.0 };
25 | tmDouble bbox_2_max[2] = { 5.0, 2.0 };
26 |
27 | tmDouble bbox_3_min[2] = {-1.1, -2.2 };
28 | tmDouble bbox_3_max[2] = { 2.2, 1.1 };
29 |
30 | mu_assert( IN_ON_BBOX(xy_1, bbox_min, bbox_max) == TRUE,
31 | "IN_ON_BBOX() gives wrong results.");
32 | mu_assert( IN_ON_BBOX(xy_2, bbox_min, bbox_max) == FALSE,
33 | "IN_ON_BBOX() gives wrong results.");
34 | mu_assert( IN_ON_BBOX(xy_3, bbox_min, bbox_max) == TRUE,
35 | "IN_ON_BBOX() gives wrong results.");
36 |
37 | mu_assert( IN_BBOX(xy_1, bbox_min, bbox_max) == TRUE,
38 | "IN_BBOX() gives wrong results.");
39 | mu_assert( IN_BBOX(xy_2, bbox_min, bbox_max) == FALSE,
40 | "IN_BBOX() gives wrong results.");
41 | mu_assert( IN_BBOX(xy_3, bbox_min, bbox_max) == FALSE,
42 | "IN_BBOX() gives wrong results.");
43 |
44 | mu_assert( ON_BBOX(xy_1, bbox_min, bbox_max) == FALSE,
45 | "ON_BBOX() gives wrong results.");
46 | mu_assert( ON_BBOX(xy_2, bbox_min, bbox_max) == FALSE,
47 | "ON_BBOX() gives wrong results.");
48 | mu_assert( ON_BBOX(xy_3, bbox_min, bbox_max) == TRUE,
49 | "ON_BBOX() gives wrong results.");
50 |
51 |
52 | mu_assert( BBOX_OVERLAP(bbox_1_min, bbox_1_max, bbox_min, bbox_max) == TRUE,
53 | "BBOX_OVERLAP() gives wrong results.");
54 | mu_assert( BBOX_OVERLAP(bbox_2_min, bbox_2_max, bbox_min, bbox_max) == FALSE,
55 | "BBOX_OVERLAP() gives wrong results.");
56 | mu_assert( BBOX_OVERLAP(bbox_3_min, bbox_3_max, bbox_min, bbox_max) == TRUE,
57 | "BBOX_OVERLAP() gives wrong results.");
58 |
59 | /*----------------------------------------------------------
60 | | In segment
61 | ----------------------------------------------------------*/
62 | tmDouble s1[2] = { 1.0, 1.0 };
63 | tmDouble s2[2] = { 4.0, 1.0 };
64 | tmDouble s3[2] = { 2.0, 1.0 };
65 | tmDouble s4[2] = { 5.0, 1.0 };
66 |
67 | mu_assert(ORIENTATION(s1, s2, s3) == 0,
68 | "ORIENTATION() gives wrong results.");
69 |
70 | mu_assert(IN_SEGMENT(s1, s2, s3) == TRUE,
71 | "IN_SEGMENT() gives wrong results.");
72 |
73 | mu_assert(IN_SEGMENT(s1, s2, s4) == FALSE,
74 | "IN_SEGMENT() gives wrong results.");
75 |
76 | mu_assert(IN_ON_SEGMENT(s1, s2, s1) == TRUE,
77 | "IN_ON_SEGMENT() gives wrong results.");
78 |
79 | mu_assert(IN_ON_SEGMENT(s1, s2, s4) == FALSE,
80 | "IN_ON_SEGMENT() gives wrong results.");
81 |
82 |
83 | /*----------------------------------------------------------
84 | | Line intersection
85 | ----------------------------------------------------------*/
86 | tmDouble n1[2] = { 1.0, 1.0 };
87 | tmDouble n2[2] = { 4.0, 1.0 };
88 | tmDouble n3[2] = { 2.0, 2.0 };
89 | tmDouble n4[2] = { 6.0, 2.0 };
90 | tmDouble n5[2] = { 8.0, 2.0 };
91 | tmDouble n6[2] = { 2.0, 5.0 };
92 | tmDouble n7[2] = { 6.0, 4.0 };
93 | tmDouble n8[2] = { 7.0, 5.0 };
94 | tmDouble n9[2] = { 8.0, 5.0 };
95 | tmDouble n10[2] = { 9.0, 5.0 };
96 | tmDouble n11[2] = { 2.0, 8.0 };
97 | tmDouble n12[2] = { 6.0, 7.0 };
98 | tmDouble n13[2] = { 6.0, 9.0 };
99 |
100 | mu_assert(INTERSECTION_IN_LINES(n1, n2, n3, n4) == FALSE,
101 | "INTERSECTION_IN_LINES() gives wrong results.");
102 | mu_assert(INTERSECTION_IN_LINES(n6, n7, n6, n13) == FALSE,
103 | "INTERSECTION_IN_LINES() gives wrong results.");
104 |
105 | mu_assert(INTERSECTION_IN_LINES(n6, n13, n11, n12) == TRUE,
106 | "INTERSECTION_IN_LINES() gives wrong results.");
107 | mu_assert(INTERSECTION_IN_LINES(n5, n9, n8, n10) == TRUE,
108 | "INTERSECTION_IN_LINES() gives wrong results.");
109 |
110 | return NULL;
111 | } /* test_geometric_functions() */
112 |
--------------------------------------------------------------------------------
/src/tmesh/test/geom_tests.h:
--------------------------------------------------------------------------------
1 | #ifndef geom_tests_h
2 | #define geom_tests_h
3 | /*************************************************************
4 | * Unit test function for geometric functions
5 | *************************************************************/
6 | char *test_geometric_functions();
7 |
8 | #endif
9 |
--------------------------------------------------------------------------------
/src/tmesh/test/tmList_tests.c:
--------------------------------------------------------------------------------
1 | #include "tmesh/minunit.h"
2 | #include "tmesh/tmList.h"
3 | #include
4 | #include "tmList_tests.h"
5 |
6 | /*************************************************************
7 | * Definition of unit test variables
8 | *************************************************************/
9 | static tmList *list = NULL;
10 | static tmList *list_jn = NULL;
11 | char *test1= "test1 data";
12 | char *test2= "test2 data";
13 | char *test3= "test3 data";
14 | char *test4= "test4 data";
15 |
16 | /*************************************************************
17 | * Definition of unit test functions
18 | *************************************************************/
19 | char *test_tmList_create()
20 | {
21 | list = tmList_create();
22 | mu_assert(list != NULL, "Failed to create list.");
23 |
24 | list_jn = tmList_create();
25 | mu_assert(list_jn != NULL, "Failed to create list.");
26 |
27 | return NULL;
28 | }
29 |
30 | char *test_tmList_push_pop()
31 | {
32 | tmList_push(list, test1);
33 | mu_assert(tmList_last(list) == test1, "Wrong last value.");
34 |
35 | tmList_push(list, test2);
36 | mu_assert(tmList_last(list) == test2, "Wrong last value.");
37 |
38 | tmList_push(list, test3);
39 | mu_assert(tmList_last(list) == test3, "Wrong last value.");
40 | mu_assert(tmList_count(list) == 3, "Wrong count on push.");
41 |
42 | char *val = tmList_pop(list);
43 | mu_assert(val == test3, "Wrong value on pop.");
44 |
45 | val = tmList_pop(list);
46 | mu_assert(val == test2, "Wrong value on pop.");
47 |
48 | val = tmList_pop(list);
49 | mu_assert(val == test1, "Wrong value on pop.");
50 | mu_assert(tmList_count(list) == 0, "Wrong count after pop.");
51 |
52 | return NULL;
53 | }
54 |
55 | char *test_tmList_unshift()
56 | {
57 | tmList_unshift(list, test1);
58 | mu_assert(tmList_first(list) == test1, "Wrong first value.");
59 |
60 | tmList_unshift(list, test2);
61 | mu_assert(tmList_first(list) == test2, "Wrong first value.");
62 |
63 | tmList_unshift(list, test3);
64 | mu_assert(tmList_first(list) == test3, "Wrong first value.");
65 | mu_assert(tmList_count(list) == 3, "Wrong count on unshift.");
66 |
67 | return NULL;
68 | }
69 |
70 | char *test_tmList_remove()
71 | {
72 | char *val = tmList_remove(list, list->first->next);
73 | mu_assert(val == test2, "Wrong removed element.");
74 | mu_assert(tmList_count(list) == 2, "Wrong count after remove.");
75 | mu_assert(tmList_first(list) == test3, "Wrong first after remove.");
76 | mu_assert(tmList_last(list) == test1, "Wrong last after remove.");
77 |
78 | return NULL;
79 | }
80 |
81 | char *test_tmList_shift()
82 | {
83 | mu_assert(tmList_count(list) != 0, "Wrong count before shift.");
84 |
85 | char *val = tmList_shift(list);
86 | mu_assert(val == test3, "Wrong value on shift.");
87 |
88 | val = tmList_shift(list);
89 | mu_assert(val == test1, "Wrong value on shift.");
90 | mu_assert(tmList_count(list) == 0, "Wrong count after shift.");
91 |
92 | return NULL;
93 | }
94 |
95 | char *test_tmList_destroy()
96 | {
97 | tmList_clear_destroy(list);
98 |
99 | return NULL;
100 | }
101 |
102 |
103 | char *test_tmList_join()
104 | {
105 | tmList_push(list, test1);
106 | mu_assert(tmList_last(list) == test1, "Wrong last value.");
107 |
108 | tmList_push(list, test2);
109 | mu_assert(tmList_last(list) == test2, "Wrong last value.");
110 |
111 | tmList_push(list_jn, test3);
112 | mu_assert(tmList_last(list_jn) == test3, "Wrong last value.");
113 |
114 | tmList_push(list_jn, test4);
115 | mu_assert(tmList_last(list_jn) == test4, "Wrong last value.");
116 |
117 | tmList_join(list, list_jn);
118 | mu_assert(tmList_count(list) == 4, "Wrong join count.");
119 | mu_assert(tmList_first(list) == test1, "Wrong join first value.");
120 | mu_assert(list->first->next->next->value == test3, "Wrong join first value.");
121 | mu_assert(tmList_last(list) == test4, "Wrong join first value.");
122 |
123 | char *val;
124 | val = tmList_pop(list);
125 | mu_assert(val == test4, "Wrong value on pop.");
126 |
127 | val = tmList_pop(list);
128 | mu_assert(val == test3, "Wrong value on pop.");
129 |
130 | val = tmList_pop(list);
131 | mu_assert(val == test2, "Wrong value on pop.");
132 |
133 | val = tmList_pop(list);
134 | mu_assert(val == test1, "Wrong value on pop.");
135 |
136 | return NULL;
137 |
138 | }
139 |
140 |
141 | char *test_tmList_split()
142 | {
143 |
144 | tmList *test_tmList = tmList_create();
145 | double test_data[5] = {1.0, 2.0, 3.0, 4.0, 5.0};
146 |
147 | int i;
148 | for (i = 0; i < 5; i++)
149 | tmList_push(test_tmList, &test_data[i]);
150 |
151 | mu_assert( test_tmList->first->prev == NULL,
152 | "Wrong list definition.");
153 | mu_assert( test_tmList->last->next == NULL,
154 | "Wrong list definition.");
155 |
156 | tmList *split_tmList = tmList_split(test_tmList, 2);
157 |
158 | mu_assert( *(double*)(split_tmList->first->value) == 3.0,
159 | "Failed to split list.");
160 | mu_assert( *(double*)(split_tmList->last->value) == 5.0,
161 | "Failed to split list.");
162 |
163 | mu_assert( *(double*)(test_tmList->first->value) == 1.0,
164 | "Failed to split list.");
165 | mu_assert( *(double*)(test_tmList->last->value) == 2.0,
166 | "Failed to split list.");
167 |
168 | mu_assert( split_tmList->first->prev == NULL,
169 | "Failed to split list.");
170 | mu_assert( test_tmList->last->next == NULL,
171 | "Failed to split list.");
172 | mu_assert( test_tmList->count == 2,
173 | "Failed to split list.");
174 | mu_assert( split_tmList->count == 3,
175 | "Failed to split list.");
176 |
177 | tmList_destroy(split_tmList);
178 |
179 | split_tmList = tmList_split(test_tmList, 0);
180 |
181 | mu_assert( split_tmList == test_tmList,
182 | "Failed to split list.");
183 |
184 | split_tmList = tmList_split(test_tmList, test_tmList->count-1);
185 |
186 | mu_assert( *(double*)(split_tmList->first->value) == 2.0,
187 | "Failed to split list.");
188 | mu_assert( *(double*)(split_tmList->last->value) == 2.0,
189 | "Failed to split list.");
190 | mu_assert( *(double*)(test_tmList->first->value) == 1.0,
191 | "Failed to split list.");
192 | mu_assert( *(double*)(test_tmList->last->value) == 1.0,
193 | "Failed to split list.");
194 | mu_assert( split_tmList->first->prev == NULL,
195 | "Failed to split list.");
196 | mu_assert( test_tmList->last->next == NULL,
197 | "Failed to split list.");
198 |
199 | mu_assert( test_tmList->count == 1,
200 | "Failed to split list.");
201 | mu_assert( split_tmList->count == 1,
202 | "Failed to split list.");
203 |
204 | tmList_destroy(split_tmList);
205 |
206 |
207 | split_tmList = tmList_split(test_tmList, 0);
208 |
209 | mu_assert( split_tmList == test_tmList,
210 | "Failed to split list.");
211 |
212 |
213 | tmList_destroy(test_tmList);
214 |
215 | return NULL;
216 | }
217 |
--------------------------------------------------------------------------------
/src/tmesh/test/tmList_tests.h:
--------------------------------------------------------------------------------
1 | #ifndef tmList_tests_h
2 | #define tmList_tests_h
3 |
4 | char *test_tmList_create();
5 | char *test_tmList_push_pop();
6 | char *test_tmList_unshift();
7 | char *test_tmList_remove();
8 | char *test_tmList_shift();
9 | char *test_tmList_destroy();
10 | char *test_tmList_join();
11 | char *test_tmList_split();
12 |
13 | #endif
14 |
--------------------------------------------------------------------------------
/src/tmesh/test/tmParam_tests.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include "tmParam_tests.h"
5 |
6 | //const char *testfile = "/datadisk/Code/C-Code/tmesh/share/files/example.para";
7 | const char *testfile = "/datadisk/Code/C-Code/tmesh/share/files/comment_test.para";
8 |
9 | /*************************************************************
10 | * Unit test function to handle creation and
11 | * destruction of bstrings
12 | *************************************************************/
13 | char *test_tmParam_readfile()
14 | {
15 | int i;
16 | bstring *ptr = NULL;
17 | tmParam *file = tmParam_create( testfile );
18 |
19 | /*----------------------------------------------------------
20 | | Return all lines without '#' Comment specifier
21 | ----------------------------------------------------------*/
22 | struct bstrList *test_1 = tmParam_popLinesWith(file->txtlist, "#");
23 |
24 | ptr = test_1->entry;
25 | bstring bcmp_1 = bfromcstr( "NODES" );
26 |
27 | for (i = 0; i < test_1->qty; i++)
28 | mu_assert( binstr(ptr[i], 0, bcmp_1) == BSTR_ERR,
29 | " failed.");
30 |
31 | /*----------------------------------------------------------
32 | | Return all lines with 'Define nodes' specifier
33 | ----------------------------------------------------------*/
34 | struct bstrList *test_2 = tmParam_getLinesWith(file->txtlist,
35 | "Define nodes:");
36 |
37 | ptr = test_2->entry;
38 | bstring bcmp_2 = bfromcstr( "Define nodes:" );
39 |
40 | for (i = 0; i < test_2->qty; i++)
41 | mu_assert(binstr(ptr[i], 0, bcmp_2) != BSTR_ERR,
42 | " failed.");
43 |
44 | /*----------------------------------------------------------
45 | | Return integer / float / bstring parameter
46 | ----------------------------------------------------------*/
47 | int int_param, check;
48 | double dbl_param;
49 | bstring bstr_param;
50 |
51 | check = tmParam_extractParam(file->txtlist,
52 | "Number of quadtree elements:", 0, &int_param);
53 | mu_assert( check == 1, " failed.");
54 | mu_assert( int_param == 50, " failed.");
55 |
56 | check = tmParam_extractParam(file->txtlist,
57 | "Global element size:", 1, &dbl_param);
58 | mu_assert( check == 1, " failed.");
59 | mu_assert( dbl_param == 0.5,
60 | " failed.");
61 |
62 | check = tmParam_extractParam(file->txtlist,
63 | "Mesh bounding box:", 2, &bstr_param);
64 | mu_assert( check == 1, " failed.");
65 | mu_assert( strcmp( " -10.0, -10.0, 20.0, 20.0", bstr_param->data) == 0,
66 | " failed.");
67 |
68 | /*----------------------------------------------------------
69 | | Return array from parameter
70 | ----------------------------------------------------------*/
71 | int *int_array;
72 | check = tmParam_extractArray(file->txtlist,
73 | "Mesh bounding box:", 0, &int_array);
74 | mu_assert( check == 1, " failed.");
75 | mu_assert( int_array[0] == -10 , " failed.");
76 | mu_assert( int_array[2] == 20 , " failed.");
77 | free(int_array);
78 |
79 | double *dbl_array;
80 | check = tmParam_extractArray(file->txtlist,
81 | "Mesh bounding box:", 1, &dbl_array);
82 | mu_assert( check == 1, " failed.");
83 | mu_assert( dbl_array[0] == -10.0 , " failed.");
84 | mu_assert( dbl_array[2] == 20.0 , " failed.");
85 | free(dbl_array);
86 |
87 | /* THIS IS NOT WORKING YET!
88 | struct bstrList *str_array;
89 | check = tmParam_extractArray(file->txtlist,
90 | "Mesh bounding box:", 2, &str_array);
91 | mu_assert( check == 1, " failed.");
92 | mu_assert( str_array->qty == 4, " failed.");
93 | bstrListDestroy(str_array); */
94 |
95 | /*----------------------------------------------------------
96 | | Read node coordinates
97 | ----------------------------------------------------------*/
98 | tmDouble (*nodes)[2];
99 | int nNodes;
100 | tmParam_readNodeCoords(file->txtlist,
101 | &nodes, &nNodes);
102 | mu_assert( nodes[0][0] == 1.0,
103 | " failed.");
104 | mu_assert( nodes[0][1] == 1.0,
105 | " failed.");
106 | mu_assert( nodes[5][0] == 2.0,
107 | " failed.");
108 | mu_assert( nodes[5][1] == 4.0,
109 | " failed.");
110 | free(nodes);
111 |
112 | /*----------------------------------------------------------
113 | | Read exterior boundary edges
114 | ----------------------------------------------------------*/
115 | int (*bdryEdges)[2];
116 | int *bdryEdgeMarker;
117 | tmDouble *bdryRefinement;
118 | int nBdryEdges;
119 | int bdryMarker;
120 |
121 | tmParam_readExtBdryData(file->txtlist,
122 | &bdryEdges, &bdryEdgeMarker, &bdryRefinement,
123 | &nBdryEdges, &bdryMarker);
124 | mu_assert( bdryMarker == 1,
125 | " failed.");
126 | mu_assert( nBdryEdges == 4,
127 | " failed.");
128 | mu_assert( bdryEdges[1][1] == 2,
129 | " failed.");
130 | mu_assert( bdryEdges[2][0] == 2,
131 | " failed.");
132 | mu_assert( bdryEdges[0][0] == 0,
133 | " failed.");
134 | mu_assert( bdryEdgeMarker[0] == 0,
135 | " failed.");
136 | mu_assert( bdryEdgeMarker[2] == 0,
137 | " failed.");
138 | mu_assert( bdryRefinement[2] == 1.4,
139 | " failed.");
140 | free(bdryEdges);
141 | free(bdryEdgeMarker);
142 | free(bdryRefinement);
143 |
144 |
145 |
146 | /*----------------------------------------------------------
147 | | Read exterior boundary edges
148 | ----------------------------------------------------------*/
149 | int (**intrEdges)[2];
150 | int **intrEdgeMarkers;
151 | tmDouble **intrEdgeRefinements;
152 | int *nIntrEdges;
153 | int *intrBdryMarkers;
154 | int nIntrBdrys;
155 |
156 | tmParam_readIntBdryData(file->txtlist,
157 | &intrEdges, &intrEdgeMarkers,
158 | &intrEdgeRefinements,
159 | &nIntrEdges, &intrBdryMarkers,
160 | &nIntrBdrys);
161 |
162 | /*
163 | int j;
164 | for (j = 0; j < nIntrBdrys; j++)
165 | {
166 | tmPrint("INTERIOR BOUNDARY %d: %d EDGES, MARKER %d",
167 | j, nIntrEdges[j], intrBdryMarkers[j]);
168 |
169 | for (i = 0; i < nIntrEdges[j]; i++)
170 | tmPrint(" %d: (%d, %d), %d, %.3f",
171 | i, intrEdges[j][i][0], intrEdges[j][i][1],
172 | intrEdgeMarkers[j][i], intrEdgeRefinements[j][i]);
173 | }
174 | */
175 |
176 | for (i = 0; i < nIntrBdrys; i++)
177 | {
178 | free(intrEdges[i]);
179 | free(intrEdgeMarkers[i]);
180 | free(intrEdgeRefinements[i]);
181 | }
182 | free(intrEdges);
183 | free(intrEdgeMarkers);
184 | free(intrEdgeRefinements);
185 | free(nIntrEdges);
186 | free(intrBdryMarkers);
187 |
188 |
189 |
190 |
191 | bdestroy(bstr_param);
192 | tmParam_destroy( file );
193 | bdestroy( bcmp_1 );
194 | bdestroy( bcmp_2 );
195 | bstrListDestroy( test_1 );
196 | bstrListDestroy( test_2 );
197 |
198 | return NULL;
199 | }
200 |
201 |
202 | /*************************************************************
203 | * Read a file and clear all strings behind a comment
204 | * identifier
205 | *************************************************************/
206 | char *test_tmParam_comments()
207 | {
208 | int i;
209 |
210 | tmParam *file = tmParam_create( testfile );
211 |
212 | /*----------------------------------------------------------
213 | | Remove all comments from the file
214 | ----------------------------------------------------------*/
215 | bstring comment_fltr = bfromcstr("#");
216 | struct bstrList *test_1 = tmParam_removeComments(file->txtlist,
217 | comment_fltr->data);
218 | bstring *fl_ptr = test_1->entry;
219 |
220 | for (i = 0; i < test_1->qty; i++)
221 | {
222 | mu_assert( binstr(fl_ptr[i], 0, comment_fltr) == BSTR_ERR,
223 | " failed.");
224 | }
225 |
226 | /*----------------------------------------------------------
227 | | Free memory
228 | ----------------------------------------------------------*/
229 | bstrListDestroy( test_1 );
230 | bdestroy( comment_fltr );
231 | tmParam_destroy( file );
232 |
233 | return NULL;
234 | }
235 |
--------------------------------------------------------------------------------
/src/tmesh/test/tmParam_tests.h:
--------------------------------------------------------------------------------
1 | #ifndef tmParam_tests_h
2 | #define tmParam_tests_h
3 |
4 | char *test_tmParam_readfile();
5 |
6 | char *test_tmParam_comments();
7 |
8 | #endif
9 |
--------------------------------------------------------------------------------
/src/tmesh/test/tmesh_cylinder.c:
--------------------------------------------------------------------------------
1 | #include "tmesh/tmNode.h"
2 | #include "tmesh/tmEdge.h"
3 | #include "tmesh/tmMesh.h"
4 | #include "tmesh/tmBdry.h"
5 |
6 | #include "tmesh/dbg.h"
7 |
8 | #include "tmesh_cylinder.h"
9 |
10 | #include
11 | #include
12 | #define _USE_MATH_DEFINES
13 | #include
14 | #include
15 |
16 | /*************************************************************
17 | *
18 | *************************************************************/
19 | static inline tmDouble size_fun( tmDouble xy[2] )
20 | {
21 | tmDouble x0 = 200.0;
22 | tmDouble y0 = 200.0;
23 |
24 | tmDouble dx = x0 - xy[0];
25 | tmDouble dy = y0 - xy[1];
26 | tmDouble r2 = dx*dx + dy*dy;
27 |
28 | if (xy[0] < 500.0)
29 | return 40.0 - 39.0 * exp(-0.00001*r2);
30 | else
31 | return 25. + 0.01*xy[0];
32 | }
33 |
34 | /*************************************************************
35 | * Function to create a mesh with a cylinder
36 | *************************************************************/
37 | char *test_mesh_cylinder()
38 | {
39 | tmDouble xy_min[2] = { -1.0, -1.0 };
40 | tmDouble xy_max[2] = { 2201.0, 411.0 };
41 | tmMesh *mesh = tmMesh_create(xy_min, xy_max, 25, 50., size_fun);
42 |
43 | /*--------------------------------------------------------
44 | | exterior boundary
45 | --------------------------------------------------------*/
46 | tmDouble xy_e0[2] = { 0.0, 0.0 };
47 | tmDouble xy_e1[2] = { 2200.0, 0.0 };
48 | tmDouble xy_e2[2] = { 2200.0, 410.0 };
49 | tmDouble xy_e3[2] = { 0.0, 410.0 };
50 |
51 | tmNode *n_e0 = tmNode_create(mesh, xy_e0);
52 | tmNode *n_e1 = tmNode_create(mesh, xy_e1);
53 | tmNode *n_e2 = tmNode_create(mesh, xy_e2);
54 | tmNode *n_e3 = tmNode_create(mesh, xy_e3);
55 |
56 | tmBdry *bdry_ext = tmMesh_addBdry(mesh, FALSE, 0);
57 |
58 | tmEdge *e_e0 = tmBdry_edgeCreate(bdry_ext, n_e0, n_e1, 0, 1.0);
59 | tmEdge *e_e1 = tmBdry_edgeCreate(bdry_ext, n_e1, n_e2, 1, 1.0);
60 | tmEdge *e_e2 = tmBdry_edgeCreate(bdry_ext, n_e2, n_e3, 2, 1.0);
61 | tmEdge *e_e3 = tmBdry_edgeCreate(bdry_ext, n_e3, n_e0, 3, 1.0);
62 |
63 |
64 | /*--------------------------------------------------------
65 | | interior boundary
66 | --------------------------------------------------------*/
67 | tmDouble xy_center[2] = { 200.0, 200.0 };
68 | int n_segs = 60;
69 | tmDouble radius = 50;
70 |
71 | tmNode *n_circ[n_segs];
72 | tmEdge *e_circ[n_segs];
73 |
74 | tmBdry *bdry_int = tmMesh_addBdry(mesh, TRUE, 1);
75 |
76 | int i;
77 | for (i=0; i ----------------------------------------------\n");
101 | printf("> cylinder mesh performance test \n");
102 | printf("> ----------------------------------------------\n");
103 | printf("> Number of elements: %d\n", mesh->no_tris);
104 | printf("> Meshing time : %e sec\n", (double) (tic_2 - tic_1) / CLOCKS_PER_SEC );
105 | printf("> ----------------------------------------------\n");
106 |
107 | /*--------------------------------------------------------
108 | | Print the mesh data
109 | --------------------------------------------------------*/
110 | tmMesh_printMesh(mesh);
111 |
112 | tmMesh_destroy(mesh);
113 |
114 | return NULL;
115 |
116 | } /* test_mesh_cylinder() */
117 |
--------------------------------------------------------------------------------
/src/tmesh/test/tmesh_cylinder.h:
--------------------------------------------------------------------------------
1 | #ifndef tmesh_tests_h
2 | #define tmesh_tests_h
3 |
4 | /*************************************************************
5 | * Function to create a mesh with a cylinder
6 | *************************************************************/
7 | char *test_mesh_cylinder();
8 |
9 | #endif
10 |
--------------------------------------------------------------------------------
/src/tmesh/test/tmesh_examples.c:
--------------------------------------------------------------------------------
1 | #include "tmesh/tmNode.h"
2 | #include "tmesh/tmEdge.h"
3 | #include "tmesh/tmTri.h"
4 | #include "tmesh/tmBdry.h"
5 | #include "tmesh/tmMesh.h"
6 | #include "tmesh/tmQtree.h"
7 | #include "tmesh/tmFront.h"
8 | #include "tmesh/tmList.h"
9 |
10 | #include "tmesh/minunit.h"
11 | #include "tmesh/dbg.h"
12 |
13 | #include "tmesh_tests.h"
14 |
15 | #include
16 | #include
17 | #define _USE_MATH_DEFINES
18 | #include
19 | #include
20 |
21 | /************************************************************
22 | * Example 1)
23 | * Simple mesh with constant size
24 | ************************************************************/
25 | char *test_example_1()
26 | {
27 | /*--------------------------------------------------------
28 | | 1) Define the mesh structure.
29 | |
30 | | xyMin, xyMax: The bounding box of the entire mesh
31 | | nElemQtree : number of elements in a QuadTree,
32 | | until it will be refined
33 | | Has only influence on the performance.
34 | | globSize : A number > 0 defining the global
35 | | element size of the mesh
36 | --------------------------------------------------------*/
37 | int nElemQtree = 50;
38 | tmDouble globSize = 1.0;
39 | tmDouble xyMin[2] = {-10.0,-10.0 };
40 | tmDouble xyMax[2] = { 20.0, 20.0 };
41 |
42 | tmMesh *mesh = tmMesh_create(xyMin, xyMax, nElemQtree,
43 | globSize, NULL);
44 |
45 | /*--------------------------------------------------------
46 | | 2) Define the mesh's exterior boundary.
47 | | The "FALSE" flag simply defines, that this boundary
48 | | is not an interior boundary.
49 | | The 0 is an identifier for this boundary, which is
50 | | given as output later, as the mesh is printed out.
51 | --------------------------------------------------------*/
52 | tmBdry *bdry_ext = tmMesh_addBdry(mesh, FALSE, 0);
53 |
54 | /*--------------------------------------------------------
55 | | 3) Define the exterior boundary edge nodes.
56 | | Each boundary edge segment consists of two directed
57 | | nodes (n1,n2), which must be defined first.
58 | | IMPORTANT: Exterior boundary edges must be defined
59 | | in a counter-clockwise manner.
60 | --------------------------------------------------------*/
61 | tmDouble xy0[2] = { -1.0, -1.0 };
62 | tmDouble xy1[2] = { 16.0, 7.0 };
63 | tmDouble xy2[2] = { -1.0, 10.0 };
64 |
65 | tmNode *n0 = tmNode_create(mesh, xy0);
66 | tmNode *n1 = tmNode_create(mesh, xy1);
67 | tmNode *n2 = tmNode_create(mesh, xy2);
68 |
69 | /*--------------------------------------------------------
70 | | 4) Define the exterior boundary edge segments.
71 | | The function takes the following parameters:
72 |
73 | | > tmBdry_edgeCreate(bdry_ext, n0, n1, marker, f)
74 | |
75 | | marker : This is a further indicator which
76 | | can be applied to each edge segment
77 | | Here, all segments have the same
78 | | indicator, but it could also be
79 | | chosen in an arbitrary manner,
80 | | depending on the application the
81 | | mesh will be used for.
82 | | This value is not related to the
83 | | boundary identifier, which was also
84 | | chosen to be 1 above.
85 | | refinement f : This factor > 1.0 defines the
86 | | refinement of the mesh elements near
87 | | the first edge node n1. Increasing
88 | | the value will lead to a larger
89 | | refinement of elements near edges
90 | | with sharp angles.
91 | --------------------------------------------------------*/
92 | tmEdge *e0 = tmBdry_edgeCreate(bdry_ext, n0, n1, 0, 1.2);
93 | tmEdge *e1 = tmBdry_edgeCreate(bdry_ext, n1, n2, 0, 1.2);
94 | tmEdge *e2 = tmBdry_edgeCreate(bdry_ext, n2, n0, 0, 1.2);
95 |
96 | /*--------------------------------------------------------
97 | | 2) Define the mesh's interior boundary.
98 | | The "TRUE" flag defines, that this boundary
99 | | is an interior boundary.
100 | | The 1 is an identifier for this boundary, which is
101 | | given as output later, as the mesh is printed out.
102 | --------------------------------------------------------*/
103 | tmBdry *bdry_int = tmMesh_addBdry(mesh, TRUE, 1);
104 |
105 | /*--------------------------------------------------------
106 | | 3) Define the interior boundary edge nodes.
107 | --------------------------------------------------------*/
108 | tmDouble xy3[2] = { 1.0, 4.0 };
109 | tmDouble xy4[2] = { 6.0, 8.0 };
110 | tmDouble xy5[2] = { 6.0, 4.0 };
111 |
112 | tmNode *n3 = tmNode_create(mesh, xy3);
113 | tmNode *n4 = tmNode_create(mesh, xy4);
114 | tmNode *n5 = tmNode_create(mesh, xy5);
115 |
116 | /*--------------------------------------------------------
117 | | 4) Define the interior boundary edge segments.
118 | | IMPORTANT: Interior boundary edges must be defined
119 | | in a clockwise manner.
120 | --------------------------------------------------------*/
121 | tmEdge *e3 = tmBdry_edgeCreate(bdry_int, n3, n4, 1, 1.6);
122 | tmEdge *e4 = tmBdry_edgeCreate(bdry_int, n4, n5, 1, 1.6);
123 | tmEdge *e5 = tmBdry_edgeCreate(bdry_int, n5, n3, 1, 1.6);
124 |
125 | /*--------------------------------------------------------
126 | | Create mesh
127 | --------------------------------------------------------*/
128 | clock_t tic_1 = clock();
129 | tmMesh_ADFMeshing(mesh);
130 | clock_t tic_2 = clock();
131 |
132 | /*--------------------------------------------------------
133 | | Print the mesh data
134 | --------------------------------------------------------*/
135 | tmMesh_printMesh(mesh);
136 |
137 | tmPrint("----------------------------------------------\n");
138 | tmPrint("Example 1 performance test \n");
139 | tmPrint("----------------------------------------------\n");
140 | tmPrint("Number of elements: %d\n", mesh->no_tris);
141 | tmPrint("Meshing time : %e sec\n",
142 | (double) (tic_2 - tic_1) / CLOCKS_PER_SEC );
143 | tmPrint("----------------------------------------------\n");
144 |
145 | tmMesh_destroy(mesh);
146 |
147 | return NULL;
148 |
149 | } /* test_example_1() */
150 |
151 | /************************************************************
152 | * Example 2)
153 | * Simple mesh with user defined size function
154 | *
155 | * First, we need to define a size function:
156 | ************************************************************/
157 | static inline tmDouble sizeFunExample( tmDouble xy[2] )
158 | {
159 | tmDouble sizeFac = 1.5;
160 | tmDouble dx = 8.0 - xy[0];
161 | tmDouble dy = 6.0 - xy[1];
162 | return sizeFac * (0.46 - 0.41 * exp(-0.05*(dx*dx+dy*dy)));
163 | }
164 | char *test_example_2()
165 | {
166 | /*--------------------------------------------------------
167 | | 1) Define the mesh structure.
168 | | The size function is now passed to the mesh as
169 | | argument on its creation.
170 | | The rest is done as before.
171 | --------------------------------------------------------*/
172 | int nElemQtree = 50;
173 | tmDouble globSize = 1.0;
174 | tmDouble xyMin[2] = {-10.0,-10.0 };
175 | tmDouble xyMax[2] = { 20.0, 20.0 };
176 |
177 | tmMesh *mesh = tmMesh_create(xyMin, xyMax, nElemQtree,
178 | globSize, sizeFunExample);
179 |
180 | /*--------------------------------------------------------
181 | | 2) Define the mesh's exterior boundary.
182 | --------------------------------------------------------*/
183 | tmBdry *bdry_ext = tmMesh_addBdry(mesh, FALSE, 0);
184 |
185 | /*--------------------------------------------------------
186 | | 3) Define the exterior boundary edge nodes.
187 | --------------------------------------------------------*/
188 | tmDouble xy0[2] = { -1.0, -1.0 };
189 | tmDouble xy1[2] = { 16.0, 7.0 };
190 | tmDouble xy2[2] = { -1.0, 10.0 };
191 |
192 | tmNode *n0 = tmNode_create(mesh, xy0);
193 | tmNode *n1 = tmNode_create(mesh, xy1);
194 | tmNode *n2 = tmNode_create(mesh, xy2);
195 |
196 | /*--------------------------------------------------------
197 | | 4) Define the exterior boundary edge segments.
198 | --------------------------------------------------------*/
199 | tmEdge *e0 = tmBdry_edgeCreate(bdry_ext, n0, n1, 0, 1.2);
200 | tmEdge *e1 = tmBdry_edgeCreate(bdry_ext, n1, n2, 0, 1.2);
201 | tmEdge *e2 = tmBdry_edgeCreate(bdry_ext, n2, n0, 0, 1.2);
202 |
203 | /*--------------------------------------------------------
204 | | 2) Define the mesh's interior boundary.
205 | --------------------------------------------------------*/
206 | tmBdry *bdry_int = tmMesh_addBdry(mesh, TRUE, 1);
207 |
208 | /*--------------------------------------------------------
209 | | 3) Define the interior boundary edge nodes.
210 | --------------------------------------------------------*/
211 | tmDouble xy3[2] = { 1.0, 4.0 };
212 | tmDouble xy4[2] = { 6.0, 8.0 };
213 | tmDouble xy5[2] = { 6.0, 4.0 };
214 |
215 | tmNode *n3 = tmNode_create(mesh, xy3);
216 | tmNode *n4 = tmNode_create(mesh, xy4);
217 | tmNode *n5 = tmNode_create(mesh, xy5);
218 |
219 | /*--------------------------------------------------------
220 | | 4) Define the interior boundary edge segments.
221 | --------------------------------------------------------*/
222 | tmEdge *e3 = tmBdry_edgeCreate(bdry_int, n3, n4, 1, 1.6);
223 | tmEdge *e4 = tmBdry_edgeCreate(bdry_int, n4, n5, 1, 1.6);
224 | tmEdge *e5 = tmBdry_edgeCreate(bdry_int, n5, n3, 1, 1.6);
225 |
226 | /*--------------------------------------------------------
227 | | Create mesh
228 | --------------------------------------------------------*/
229 | clock_t tic_1 = clock();
230 | tmMesh_ADFMeshing(mesh);
231 | clock_t tic_2 = clock();
232 |
233 | /*--------------------------------------------------------
234 | | Print the mesh data
235 | --------------------------------------------------------*/
236 | tmMesh_printMesh(mesh);
237 |
238 | tmPrint("----------------------------------------------\n");
239 | tmPrint("Example 2 performance test \n");
240 | tmPrint("----------------------------------------------\n");
241 | tmPrint("Number of elements: %d\n", mesh->no_tris);
242 | tmPrint("Meshing time : %e sec\n",
243 | (double) (tic_2 - tic_1) / CLOCKS_PER_SEC );
244 | tmPrint("----------------------------------------------\n");
245 |
246 | tmMesh_destroy(mesh);
247 |
248 | return NULL;
249 |
250 |
251 |
252 | } /* test_example_2() */
253 |
--------------------------------------------------------------------------------
/src/tmesh/test/tmesh_examples.h:
--------------------------------------------------------------------------------
1 | #ifndef tmesh_examples_h
2 | #define tmesh_examples_h
3 |
4 | /************************************************************
5 | * Example 1)
6 | * Simple mesh with constant size
7 | ************************************************************/
8 | char *test_example_1();
9 |
10 | /************************************************************
11 | * Example 2)
12 | * Simple mesh with user defined size function
13 | ************************************************************/
14 | char *test_example_2();
15 |
16 | #endif
17 |
--------------------------------------------------------------------------------
/src/tmesh/test/tmesh_tests.h:
--------------------------------------------------------------------------------
1 | #ifndef tmesh_tests_h
2 | #define tmesh_tests_h
3 |
4 | /*************************************************************
5 | * Unit test function to handle creation and
6 | * destruction of a mesh structure
7 | *************************************************************/
8 | char *test_mesh_create_destroy();
9 |
10 | /************************************************************
11 | * Unit test function to test if an object can be located
12 | * within the domain
13 | ************************************************************/
14 | char *test_tmMesh_objInside();
15 |
16 | /*************************************************************
17 | * Unit test function to the boundary refinement
18 | ************************************************************/
19 | char *test_tmBdry_refine();
20 |
21 | /*************************************************************
22 | * Unit test function to handle the tmQtree structure
23 | *
24 | * Maximum number of qtree-objects must be set to 3 !
25 | * in order to get this test running
26 | ************************************************************/
27 | char *test_tmQtree();
28 |
29 | /************************************************************
30 | * Unit test function to handle the tmQtree structure
31 | *
32 | * Maximum number of qtree-objects must be set to 2
33 | * in order to get this test running
34 | ************************************************************/
35 | char *test_tmQtree_2();
36 |
37 | /*************************************************************
38 | * Unit test function to handle the tmQtree performance
39 | ************************************************************/
40 | char *test_tmQtree_performance();
41 |
42 | /*************************************************************
43 | * Unit test function to handle the tmQtree performance
44 | ************************************************************/
45 | char *test_tmQtree_performance2();
46 |
47 | /*************************************************************
48 | * Unit test function for the triangle intersection
49 | ************************************************************/
50 | char *test_tmTri_intersection();
51 |
52 | /*************************************************************
53 | * Unit test function for the advancing front algorithm
54 | ************************************************************/
55 | char *test_tmFront_init();
56 | char *test_tmFront_advance();
57 | char *test_tmFront_simpleMesh();
58 | char *test_tmFront_simpleMesh2();
59 | char *test_tmFront_innerOuterMesh();
60 | char *test_tmFront_tMesh();
61 |
62 | /************************************************************
63 | * Unit test function to handle the automatic sizeFunction
64 | * at boundary edges
65 | ************************************************************/
66 | char *test_tmBdry_sizeFunction();
67 |
68 | #endif
69 |
--------------------------------------------------------------------------------
/src/tmesh/test/unit_tests.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "tmesh/minunit.h"
3 | #include "tmesh/dbg.h"
4 | #include "tmesh_tests.h"
5 | #include "tmList_tests.h"
6 | #include "tmParam_tests.h"
7 | #include "tmesh_cylinder.h"
8 | #include "geom_tests.h"
9 | #include "tmesh_examples.h"
10 |
11 | /************************************************************
12 | * Run all unit test functions
13 | ************************************************************/
14 | char *all_tests()
15 | {
16 | mu_suite_start();
17 |
18 | /**********************************************************
19 | * Unit tests for list structure
20 | **********************************************************
21 | mu_run_test(test_tmList_create);
22 | mu_run_test(test_tmList_push_pop);
23 | mu_run_test(test_tmList_unshift);
24 | mu_run_test(test_tmList_remove);
25 | mu_run_test(test_tmList_shift);
26 | mu_run_test(test_tmList_join);
27 | mu_run_test(test_tmList_destroy);
28 | mu_run_test(test_tmList_split);*/
29 |
30 | /**********************************************************
31 | * Unit tests for parameter file reader
32 | **********************************************************/
33 | //mu_run_test(test_tmParam_readfile);
34 | mu_run_test(test_tmParam_comments);
35 |
36 | /**********************************************************
37 | * Unit tests for tmesh library
38 | **********************************************************/
39 | //mu_run_test(test_geometric_functions);
40 | //mu_run_test(test_tmTri_intersection);
41 | //mu_run_test(test_mesh_create_destroy);
42 | //mu_run_test(test_tmMesh_objInside);
43 | //mu_run_test(test_tmQtree);
44 | //mu_run_test(test_tmQtree_2);
45 | //mu_run_test(test_tmQtree_performance);
46 | //mu_run_test(test_tmQtree_performance2);
47 | //mu_run_test(test_tmBdry_refine);
48 | //mu_run_test(test_tmFront_init);
49 | //mu_run_test(test_tmFront_advance);
50 | //mu_run_test(test_tmFront_simpleMesh);
51 | //mu_run_test(test_tmFront_simpleMesh2);
52 | //mu_run_test(test_tmFront_innerOuterMesh);
53 | //mu_run_test(test_tmFront_tMesh);
54 | //mu_run_test(test_tmQuad_transformation);
55 |
56 | //mu_run_test(test_tmBdry_sizeFunction);
57 |
58 | //mu_run_test(test_mesh_cylinder);
59 |
60 |
61 | /**********************************************************
62 | * TMesh Examples
63 | **********************************************************/
64 | //mu_run_test(test_example_1);
65 | //mu_run_test(test_example_2);
66 |
67 |
68 | return NULL;
69 | }
70 |
71 |
72 | /************************************************************
73 | * Main function to run unit tests
74 | ************************************************************/
75 | int main(int argc, char *argv[])
76 | {
77 | debug("----- RUNNING %s\n", argv[0]);
78 |
79 | char *result;
80 | result = all_tests();
81 |
82 | if (result != 0)
83 | {
84 | debug("FAILED: %s\n", result);
85 | }
86 | else
87 | {
88 | debug("\nALL TESTS PASSED!\n");
89 | }
90 |
91 | mu_print_tests_run();
92 |
93 | exit(result != 0);
94 | }
95 |
--------------------------------------------------------------------------------