├── CMakeLists.txt ├── README ├── example.poly ├── makefile ├── LICENSE └── tetgen.h /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(tetgen) 3 | 4 | option(BUILD_EXECUTABLE "Build tetgen executable" OFF) 5 | option(BUILD_LIBRARY "Build libtetgen library" ON) 6 | 7 | if(BUILD_LIBRARY) 8 | add_library(tetgen STATIC tetgen.cxx predicates.cxx) 9 | target_compile_definitions(tetgen PRIVATE -DTETLIBRARY) 10 | # Generate position independent code 11 | set_target_properties(tetgen PROPERTIES POSITION_INDEPENDENT_CODE ON) 12 | endif() 13 | 14 | 15 | if(BUILD_EXECUTABLE) 16 | add_executable(tetgen_exec tetgen.cxx predicates.cxx) 17 | set_target_properties(tetgen_exec PROPERTIES OUTPUT_NAME tetgen) 18 | endif() 19 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This is TetGen version 1.6.0 (released on August 31, 2020) 2 | 3 | Please see the documentation of TetGen for compiling and using TetGen. 4 | It is available at the following link: 5 | 6 | http://www.tetgen.org 7 | 8 | For more information on this product, contact : 9 | 10 | Hang Si 11 | Research Group of Numerical Mathematics and Scientific Computing 12 | Weierstrass Institute for Applied Analysis and Stochastics 13 | Mohrenstr. 39 14 | 10117 Berlin, Germany 15 | 16 | EMail: 17 | Web Site: http://www.wias-berlin.de/~si 18 | 19 | ------------------- IMPORTANCE NOTICE ----------------------------- 20 | 21 | BEFORE INTALLING OR USING TetGen(R) READ the 22 | GENERAL LICENSE TERMS AND CONDITIONS 23 | 24 | ------------------------------------------------------------------- -------------------------------------------------------------------------------- /example.poly: -------------------------------------------------------------------------------- 1 | 28 3 0 1 2 | 1 0 0 0 1 3 | 2 2 0 0 1 4 | 3 2 2 0 1 5 | 4 0 2 0 1 6 | 5 0 0 4 9 7 | 6 2 0 4 9 8 | 7 2 2 3 9 9 | 8 0 2 3 9 10 | 9 0 0 5 2 11 | 10 2 0 5 2 12 | 11 2 2 5 2 13 | 12 0 2 5 2 14 | 13 0.25 0.25 0.5 4 15 | 14 1.75 0.25 0.5 4 16 | 15 1.75 1.5 0.5 4 17 | 16 0.25 1.5 0.5 4 18 | 17 0.25 0.25 1 4 19 | 18 1.75 0.25 1 4 20 | 19 1.75 1.5 1 4 21 | 20 0.25 1.5 1 4 22 | 21 0.25 0 2 4 23 | 22 1.75 0 2 4 24 | 23 1.75 1.5 2 4 25 | 24 0.25 1.5 2 4 26 | 25 0.25 0 2.5 4 27 | 26 1.75 0 2.5 4 28 | 27 1.75 1.5 2.5 4 29 | 28 0.25 1.5 2.5 4 30 | 23 1 31 | 1 0 1 # 1 32 | 4 1 2 3 4 33 | 1 0 9 # 2 34 | 4 5 6 7 8 35 | 2 1 3 # 3 36 | 4 1 2 6 5 37 | 4 21 22 26 25 38 | 1 1 0 2.25 39 | 1 0 3 # 4 40 | 4 2 3 7 6 41 | 1 0 3 # 5 42 | 4 3 4 8 7 43 | 1 0 3 # 6 44 | 4 4 1 5 8 45 | 1 0 2 # 7 46 | 4 9 10 11 12 47 | 1 0 3 # 8 48 | 4 9 10 6 5 49 | 1 0 3 # 9 50 | 4 10 11 7 6 51 | 1 0 3 # 10 52 | 4 11 12 8 7 53 | 1 0 3 # 11 54 | 4 12 9 5 8 55 | 1 0 4 # 12 56 | 4 13 14 15 16 57 | 1 0 4 # 13 58 | 4 17 18 19 20 59 | 1 0 4 # 14 60 | 4 13 14 18 17 61 | 1 0 4 # 15 62 | 4 14 15 19 18 63 | 1 0 4 # 16 64 | 4 15 16 20 19 65 | 1 0 4 # 17 66 | 4 16 13 17 20 67 | 1 0 4 # 18 68 | 4 21 22 23 24 69 | 1 0 4 # 19 70 | 4 25 26 27 28 71 | 1 0 4 # 20 72 | 4 21 22 26 25 73 | 1 0 4 # 21 74 | 4 22 23 27 26 75 | 1 0 4 # 22 76 | 4 23 24 28 27 77 | 1 0 4 # 23 78 | 4 24 21 25 28 79 | 2 80 | 1 1 0.4 2.25 81 | 2 1 0.4 0.75 82 | 2 83 | 1 1 0.25 0.1 10 0.001 84 | 2 1 0.5 4 20 0.01 85 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # # 3 | # makefile for TetGen # 4 | # # 5 | # Type "make" to compile TetGen into an executable program (tetgen). # 6 | # Type "make tetlib" to compile TetGen into a library (libtet.a). # 7 | # Type "make distclean" to delete all object (*.o) files. # 8 | # # 9 | ############################################################################### 10 | 11 | # CXX should be set to the name of your favorite C++ compiler. 12 | # =========================================================== 13 | 14 | CXX = g++ 15 | #CXX = icpc 16 | #CXX = CC 17 | 18 | # CXXFLAGS is the level of optimiztion, default is -O. One should try 19 | # -O2, -O3 ... to find the best optimization level. 20 | # =================================================================== 21 | 22 | CXXFLAGS = -O3 23 | 24 | # PREDCXXFLAGS is for compiling J. Shewchuk's predicates. 25 | 26 | PREDCXXFLAGS = -O0 27 | 28 | # SWITCHES is a list of switches to compile TetGen. 29 | # ================================================= 30 | # 31 | # By default, TetGen uses double precision floating point numbers. If you 32 | # prefer single precision, use the -DSINGLE switch. 33 | # 34 | # The source code of TetGen includes a lot of assertions, which are mainly 35 | # used for catching bugs at that places. These assertions somewhat slow 36 | # down the speed of TetGen. They can be skipped by define the -DNDEBUG 37 | # switch. 38 | 39 | SWITCHES = 40 | 41 | # RM should be set to the name of your favorite rm (file deletion program). 42 | 43 | RM = /bin/rm 44 | 45 | # The action starts here. 46 | 47 | tetgen: tetgen.cxx predicates.o 48 | $(CXX) $(CXXFLAGS) $(SWITCHES) -o tetgen tetgen.cxx predicates.o -lm 49 | 50 | tetlib: tetgen.cxx predicates.o 51 | $(CXX) $(CXXFLAGS) $(SWITCHES) -DTETLIBRARY -c tetgen.cxx 52 | ar r libtet.a tetgen.o predicates.o 53 | 54 | predicates.o: predicates.cxx 55 | $(CXX) $(PREDCXXFLAGS) -c predicates.cxx 56 | 57 | clean: 58 | $(RM) *.o *.a tetgen *~ 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | TetGen License 2 | -------------- 3 | 4 | TetGen is distributed under a dual licensing scheme. You can 5 | redistribute it and/or modify it under the terms of the GNU Affero 6 | General Public License as published by the Free Software Foundation, 7 | either version 3 of the License, or (at your option) any later 8 | version. A copy of the GNU Affero General Public License is reproduced 9 | below. 10 | 11 | If the terms and conditions of the AGPL v.3. would prevent you from 12 | using TetGen, please consider the option to obtain a commercial 13 | license for a fee. These licenses are offered by the Weierstrass 14 | Institute for Applied Analysis and Stochastics (WIAS). As a rule, 15 | licenses are provided "as-is", unlimited in time for a one time 16 | fee. Please send corresponding requests to: 17 | tetgen@wias-berlin.de. Please do not forget to include some 18 | description of your company and the realm of its activities. 19 | 20 | ===================================================================== 21 | GNU AFFERO GENERAL PUBLIC LICENSE 22 | 23 | Version 3, 19 November 2007 24 | 25 | Copyright © 2007 Free Software Foundation, Inc. 26 | Everyone is permitted to copy and distribute verbatim copies of this 27 | license document, but changing it is not allowed. 28 | 29 | Preamble 30 | 31 | The GNU Affero General Public License is a free, copyleft license for 32 | software and other kinds of works, specifically designed to ensure 33 | cooperation with the community in the case of network server software. 34 | 35 | The licenses for most software and other practical works are designed 36 | to take away your freedom to share and change the works. By contrast, 37 | our General Public Licenses are intended to guarantee your freedom to 38 | share and change all versions of a program--to make sure it remains 39 | free software for all its users. 40 | 41 | When we speak of free software, we are referring to freedom, not 42 | price. Our General Public Licenses are designed to make sure that you 43 | have the freedom to distribute copies of free software (and charge for 44 | them if you wish), that you receive source code or can get it if you 45 | want it, that you can change the software or use pieces of it in new 46 | free programs, and that you know you can do these things. 47 | 48 | Developers that use our General Public Licenses protect your rights 49 | with two steps: (1) assert copyright on the software, and (2) offer 50 | you this License which gives you legal permission to copy, distribute 51 | and/or modify the software. 52 | 53 | A secondary benefit of defending all users' freedom is that 54 | improvements made in alternate versions of the program, if they 55 | receive widespread use, become available for other developers to 56 | incorporate. Many developers of free software are heartened and 57 | encouraged by the resulting cooperation. However, in the case of 58 | software used on network servers, this result may fail to come 59 | about. The GNU General Public License permits making a modified 60 | version and letting the public access it on a server without ever 61 | releasing its source code to the public. 62 | 63 | The GNU Affero General Public License is designed specifically to 64 | ensure that, in such cases, the modified source code becomes available 65 | to the community. It requires the operator of a network server to 66 | provide the source code of the modified version running there to the 67 | users of that server. Therefore, public use of a modified version, on 68 | a publicly accessible server, gives the public access to the source 69 | code of the modified version. 70 | 71 | An older license, called the Affero General Public License and 72 | published by Affero, was designed to accomplish similar goals. This is 73 | a different license, not a version of the Affero GPL, but Affero has 74 | released a new version of the Affero GPL which permits relicensing 75 | under this license. 76 | 77 | The precise terms and conditions for copying, distribution and 78 | modification follow. 79 | 80 | TERMS AND CONDITIONS 81 | 82 | 0. Definitions. 83 | 84 | "This License" refers to version 3 of the GNU Affero General Public 85 | License. 86 | 87 | "Copyright" also means copyright-like laws that apply to other kinds 88 | of works, such as semiconductor masks. 89 | 90 | "The Program" refers to any copyrightable work licensed under this 91 | License. Each licensee is addressed as "you". "Licensees" and 92 | "recipients" may be individuals or organizations. 93 | 94 | To "modify" a work means to copy from or adapt all or part of the work 95 | in a fashion requiring copyright permission, other than the making of 96 | an exact copy. The resulting work is called a "modified version" of 97 | the earlier work or a work "based on" the earlier work. 98 | 99 | A "covered work" means either the unmodified Program or a work based 100 | on the Program. 101 | 102 | To "propagate" a work means to do anything with it that, without 103 | permission, would make you directly or secondarily liable for 104 | infringement under applicable copyright law, except executing it on a 105 | computer or modifying a private copy. Propagation includes copying, 106 | distribution (with or without modification), making available to the 107 | public, and in some countries other activities as well. 108 | 109 | To "convey" a work means any kind of propagation that enables other 110 | parties to make or receive copies. Mere interaction with a user 111 | through a computer network, with no transfer of a copy, is not 112 | conveying. 113 | 114 | An interactive user interface displays "Appropriate Legal Notices" to 115 | the extent that it includes a convenient and prominently visible 116 | feature that (1) displays an appropriate copyright notice, and (2) 117 | tells the user that there is no warranty for the work (except to the 118 | extent that warranties are provided), that licensees may convey the 119 | work under this License, and how to view a copy of this License. If 120 | the interface presents a list of user commands or options, such as a 121 | menu, a prominent item in the list meets this criterion. 122 | 123 | 1. Source Code. 124 | 125 | The "source code" for a work means the preferred form of the work for 126 | making modifications to it. "Object code" means any non-source form of 127 | a work. 128 | 129 | A "Standard Interface" means an interface that either is an official 130 | standard defined by a recognized standards body, or, in the case of 131 | interfaces specified for a particular programming language, one that 132 | is widely used among developers working in that language. 133 | 134 | The "System Libraries" of an executable work include anything, other 135 | than the work as a whole, that (a) is included in the normal form of 136 | packaging a Major Component, but which is not part of that Major 137 | Component, and (b) serves only to enable use of the work with that 138 | Major Component, or to implement a Standard Interface for which an 139 | implementation is available to the public in source code form. A 140 | "Major Component", in this context, means a major essential component 141 | (kernel, window system, and so on) of the specific operating system 142 | (if any) on which the executable work runs, or a compiler used to 143 | produce the work, or an object code interpreter used to run it. 144 | 145 | The "Corresponding Source" for a work in object code form means all 146 | the source code needed to generate, install, and (for an executable 147 | work) run the object code and to modify the work, including scripts to 148 | control those activities. However, it does not include the work's 149 | System Libraries, or general-purpose tools or generally available free 150 | programs which are used unmodified in performing those activities but 151 | which are not part of the work. For example, Corresponding Source 152 | includes interface definition files associated with source files for 153 | the work, and the source code for shared libraries and dynamically 154 | linked subprograms that the work is specifically designed to require, 155 | such as by intimate data communication or control flow between those 156 | subprograms and other parts of the work. 157 | 158 | The Corresponding Source need not include anything that users can 159 | regenerate automatically from other parts of the Corresponding Source. 160 | 161 | The Corresponding Source for a work in source code form is that same 162 | work. 163 | 164 | 2. Basic Permissions. 165 | 166 | All rights granted under this License are granted for the term of 167 | copyright on the Program, and are irrevocable provided the stated 168 | conditions are met. This License explicitly affirms your unlimited 169 | permission to run the unmodified Program. The output from running a 170 | covered work is covered by this License only if the output, given its 171 | content, constitutes a covered work. This License acknowledges your 172 | rights of fair use or other equivalent, as provided by copyright law. 173 | 174 | You may make, run and propagate covered works that you do not convey, 175 | without conditions so long as your license otherwise remains in 176 | force. You may convey covered works to others for the sole purpose of 177 | having them make modifications exclusively for you, or provide you 178 | with facilities for running those works, provided that you comply with 179 | the terms of this License in conveying all material for which you do 180 | not control copyright. Those thus making or running the covered works 181 | for you must do so exclusively on your behalf, under your direction 182 | and control, on terms that prohibit them from making any copies of 183 | your copyrighted material outside their relationship with you. 184 | 185 | Conveying under any other circumstances is permitted solely under the 186 | conditions stated below. Sublicensing is not allowed; section 10 makes 187 | it unnecessary. 188 | 189 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 190 | 191 | No covered work shall be deemed part of an effective technological 192 | measure under any applicable law fulfilling obligations under article 193 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 194 | similar laws prohibiting or restricting circumvention of such 195 | measures. 196 | 197 | When you convey a covered work, you waive any legal power to forbid 198 | circumvention of technological measures to the extent such 199 | circumvention is effected by exercising rights under this License with 200 | respect to the covered work, and you disclaim any intention to limit 201 | operation or modification of the work as a means of enforcing, against 202 | the work's users, your or third parties' legal rights to forbid 203 | circumvention of technological measures. 204 | 205 | 4. Conveying Verbatim Copies. 206 | 207 | You may convey verbatim copies of the Program's source code as you 208 | receive it, in any medium, provided that you conspicuously and 209 | appropriately publish on each copy an appropriate copyright notice; 210 | keep intact all notices stating that this License and any 211 | non-permissive terms added in accord with section 7 apply to the code; 212 | keep intact all notices of the absence of any warranty; and give all 213 | recipients a copy of this License along with the Program. 214 | 215 | You may charge any price or no price for each copy that you convey, 216 | and you may offer support or warranty protection for a fee. 217 | 218 | 5. Conveying Modified Source Versions. 219 | 220 | You may convey a work based on the Program, or the modifications to 221 | produce it from the Program, in the form of source code under the 222 | terms of section 4, provided that you also meet all of these 223 | conditions: 224 | 225 | a) The work must carry prominent notices stating that you modified it, 226 | and giving a relevant date. b) The work must carry prominent notices 227 | stating that it is released under this License and any conditions 228 | added under section 7. This requirement modifies the requirement in 229 | section 4 to "keep intact all notices". c) You must license the 230 | entire work, as a whole, under this License to anyone who comes into 231 | possession of a copy. This License will therefore apply, along with 232 | any applicable section 7 additional terms, to the whole of the work, 233 | and all its parts, regardless of how they are packaged. This License 234 | gives no permission to license the work in any other way, but it does 235 | not invalidate such permission if you have separately received it. d) 236 | If the work has interactive user interfaces, each must display 237 | Appropriate Legal Notices; however, if the Program has interactive 238 | interfaces that do not display Appropriate Legal Notices, your work 239 | need not make them do so. A compilation of a covered work with other 240 | separate and independent works, which are not by their nature 241 | extensions of the covered work, and which are not combined with it 242 | such as to form a larger program, in or on a volume of a storage or 243 | distribution medium, is called an "aggregate" if the compilation and 244 | its resulting copyright are not used to limit the access or legal 245 | rights of the compilation's users beyond what the individual works 246 | permit. Inclusion of a covered work in an aggregate does not cause 247 | this License to apply to the other parts of the aggregate. 248 | 249 | 6. Conveying Non-Source Forms. 250 | 251 | You may convey a covered work in object code form under the terms of 252 | sections 4 and 5, provided that you also convey the machine-readable 253 | Corresponding Source under the terms of this License, in one of these 254 | ways: 255 | 256 | a) Convey the object code in, or embodied in, a physical product 257 | (including a physical distribution medium), accompanied by the 258 | Corresponding Source fixed on a durable physical medium customarily 259 | used for software interchange. b) Convey the object code in, or 260 | embodied in, a physical product (including a physical distribution 261 | medium), accompanied by a written offer, valid for at least three 262 | years and valid for as long as you offer spare parts or customer 263 | support for that product model, to give anyone who possesses the 264 | object code either (1) a copy of the Corresponding Source for all the 265 | software in the product that is covered by this License, on a durable 266 | physical medium customarily used for software interchange, for a price 267 | no more than your reasonable cost of physically performing this 268 | conveying of source, or (2) access to copy the Corresponding Source 269 | from a network server at no charge. c) Convey individual copies of 270 | the object code with a copy of the written offer to provide the 271 | Corresponding Source. This alternative is allowed only occasionally 272 | and noncommercially, and only if you received the object code with 273 | such an offer, in accord with subsection 6b. d) Convey the object 274 | code by offering access from a designated place (gratis or for a 275 | charge), and offer equivalent access to the Corresponding Source in 276 | the same way through the same place at no further charge. You need not 277 | require recipients to copy the Corresponding Source along with the 278 | object code. If the place to copy the object code is a network server, 279 | the Corresponding Source may be on a different server (operated by you 280 | or a third party) that supports equivalent copying facilities, 281 | provided you maintain clear directions next to the object code saying 282 | where to find the Corresponding Source. Regardless of what server 283 | hosts the Corresponding Source, you remain obligated to ensure that it 284 | is available for as long as needed to satisfy these requirements. e) 285 | Convey the object code using peer-to-peer transmission, provided you 286 | inform other peers where the object code and Corresponding Source of 287 | the work are being offered to the general public at no charge under 288 | subsection 6d. A separable portion of the object code, whose source 289 | code is excluded from the Corresponding Source as a System Library, 290 | need not be included in conveying the object code work. 291 | 292 | A "User Product" is either (1) a "consumer product", which means any 293 | tangible personal property which is normally used for personal, 294 | family, or household purposes, or (2) anything designed or sold for 295 | incorporation into a dwelling. In determining whether a product is a 296 | consumer product, doubtful cases shall be resolved in favor of 297 | coverage. For a particular product received by a particular user, 298 | "normally used" refers to a typical or common use of that class of 299 | product, regardless of the status of the particular user or of the way 300 | in which the particular user actually uses, or expects or is expected 301 | to use, the product. A product is a consumer product regardless of 302 | whether the product has substantial commercial, industrial or 303 | non-consumer uses, unless such uses represent the only significant 304 | mode of use of the product. 305 | 306 | "Installation Information" for a User Product means any methods, 307 | procedures, authorization keys, or other information required to 308 | install and execute modified versions of a covered work in that User 309 | Product from a modified version of its Corresponding Source. The 310 | information must suffice to ensure that the continued functioning of 311 | the modified object code is in no case prevented or interfered with 312 | solely because modification has been made. 313 | 314 | If you convey an object code work under this section in, or with, or 315 | specifically for use in, a User Product, and the conveying occurs as 316 | part of a transaction in which the right of possession and use of the 317 | User Product is transferred to the recipient in perpetuity or for a 318 | fixed term (regardless of how the transaction is characterized), the 319 | Corresponding Source conveyed under this section must be accompanied 320 | by the Installation Information. But this requirement does not apply 321 | if neither you nor any third party retains the ability to install 322 | modified object code on the User Product (for example, the work has 323 | been installed in ROM). 324 | 325 | The requirement to provide Installation Information does not include a 326 | requirement to continue to provide support service, warranty, or 327 | updates for a work that has been modified or installed by the 328 | recipient, or for the User Product in which it has been modified or 329 | installed. Access to a network may be denied when the modification 330 | itself materially and adversely affects the operation of the network 331 | or violates the rules and protocols for communication across the 332 | network. 333 | 334 | Corresponding Source conveyed, and Installation Information provided, 335 | in accord with this section must be in a format that is publicly 336 | documented (and with an implementation available to the public in 337 | source code form), and must require no special password or key for 338 | unpacking, reading or copying. 339 | 340 | 7. Additional Terms. 341 | 342 | "Additional permissions" are terms that supplement the terms of this 343 | License by making exceptions from one or more of its 344 | conditions. Additional permissions that are applicable to the entire 345 | Program shall be treated as though they were included in this License, 346 | to the extent that they are valid under applicable law. If additional 347 | permissions apply only to part of the Program, that part may be used 348 | separately under those permissions, but the entire Program remains 349 | governed by this License without regard to the additional permissions. 350 | 351 | When you convey a copy of a covered work, you may at your option 352 | remove any additional permissions from that copy, or from any part of 353 | it. (Additional permissions may be written to require their own 354 | removal in certain cases when you modify the work.) You may place 355 | additional permissions on material, added by you to a covered work, 356 | for which you have or can give appropriate copyright permission. 357 | 358 | Notwithstanding any other provision of this License, for material you 359 | add to a covered work, you may (if authorized by the copyright holders 360 | of that material) supplement the terms of this License with terms: 361 | 362 | a) Disclaiming warranty or limiting liability differently from the 363 | terms of sections 15 and 16 of this License; or b) Requiring 364 | preservation of specified reasonable legal notices or author 365 | attributions in that material or in the Appropriate Legal Notices 366 | displayed by works containing it; or c) Prohibiting misrepresentation 367 | of the origin of that material, or requiring that modified versions of 368 | such material be marked in reasonable ways as different from the 369 | original version; or d) Limiting the use for publicity purposes of 370 | names of licensors or authors of the material; or e) Declining to 371 | grant rights under trademark law for use of some trade names, 372 | trademarks, or service marks; or f) Requiring indemnification of 373 | licensors and authors of that material by anyone who conveys the 374 | material (or modified versions of it) with contractual assumptions of 375 | liability to the recipient, for any liability that these contractual 376 | assumptions directly impose on those licensors and authors. All other 377 | non-permissive additional terms are considered "further restrictions" 378 | within the meaning of section 10. If the Program as you received it, 379 | or any part of it, contains a notice stating that it is governed by 380 | this License along with a term that is a further restriction, you may 381 | remove that term. If a license document contains a further restriction 382 | but permits relicensing or conveying under this License, you may add 383 | to a covered work material governed by the terms of that license 384 | document, provided that the further restriction does not survive such 385 | relicensing or conveying. 386 | 387 | If you add terms to a covered work in accord with this section, you 388 | must place, in the relevant source files, a statement of the 389 | additional terms that apply to those files, or a notice indicating 390 | where to find the applicable terms. 391 | 392 | Additional terms, permissive or non-permissive, may be stated in the 393 | form of a separately written license, or stated as exceptions; the 394 | above requirements apply either way. 395 | 396 | 8. Termination. 397 | 398 | You may not propagate or modify a covered work except as expressly 399 | provided under this License. Any attempt otherwise to propagate or 400 | modify it is void, and will automatically terminate your rights under 401 | this License (including any patent licenses granted under the third 402 | paragraph of section 11). 403 | 404 | However, if you cease all violation of this License, then your license 405 | from a particular copyright holder is reinstated (a) provisionally, 406 | unless and until the copyright holder explicitly and finally 407 | terminates your license, and (b) permanently, if the copyright holder 408 | fails to notify you of the violation by some reasonable means prior to 409 | 60 days after the cessation. 410 | 411 | Moreover, your license from a particular copyright holder is 412 | reinstated permanently if the copyright holder notifies you of the 413 | violation by some reasonable means, this is the first time you have 414 | received notice of violation of this License (for any work) from that 415 | copyright holder, and you cure the violation prior to 30 days after 416 | your receipt of the notice. 417 | 418 | Termination of your rights under this section does not terminate the 419 | licenses of parties who have received copies or rights from you under 420 | this License. If your rights have been terminated and not permanently 421 | reinstated, you do not qualify to receive new licenses for the same 422 | material under section 10. 423 | 424 | 9. Acceptance Not Required for Having Copies. 425 | 426 | You are not required to accept this License in order to receive or run 427 | a copy of the Program. Ancillary propagation of a covered work 428 | occurring solely as a consequence of using peer-to-peer transmission 429 | to receive a copy likewise does not require acceptance. However, 430 | nothing other than this License grants you permission to propagate or 431 | modify any covered work. These actions infringe copyright if you do 432 | not accept this License. Therefore, by modifying or propagating a 433 | covered work, you indicate your acceptance of this License to do so. 434 | 435 | 10. Automatic Licensing of Downstream Recipients. 436 | 437 | Each time you convey a covered work, the recipient automatically 438 | receives a license from the original licensors, to run, modify and 439 | propagate that work, subject to this License. You are not responsible 440 | for enforcing compliance by third parties with this License. 441 | 442 | An "entity transaction" is a transaction transferring control of an 443 | organization, or substantially all assets of one, or subdividing an 444 | organization, or merging organizations. If propagation of a covered 445 | work results from an entity transaction, each party to that 446 | transaction who receives a copy of the work also receives whatever 447 | licenses to the work the party's predecessor in interest had or could 448 | give under the previous paragraph, plus a right to possession of the 449 | Corresponding Source of the work from the predecessor in interest, if 450 | the predecessor has it or can get it with reasonable efforts. 451 | 452 | You may not impose any further restrictions on the exercise of the 453 | rights granted or affirmed under this License. For example, you may 454 | not impose a license fee, royalty, or other charge for exercise of 455 | rights granted under this License, and you may not initiate litigation 456 | (including a cross-claim or counterclaim in a lawsuit) alleging that 457 | any patent claim is infringed by making, using, selling, offering for 458 | sale, or importing the Program or any portion of it. 459 | 460 | 11. Patents. 461 | 462 | A "contributor" is a copyright holder who authorizes use under this 463 | License of the Program or a work on which the Program is based. The 464 | work thus licensed is called the contributor's "contributor version". 465 | 466 | A contributor's "essential patent claims" are all patent claims owned 467 | or controlled by the contributor, whether already acquired or 468 | hereafter acquired, that would be infringed by some manner, permitted 469 | by this License, of making, using, or selling its contributor version, 470 | but do not include claims that would be infringed only as a 471 | consequence of further modification of the contributor version. For 472 | purposes of this definition, "control" includes the right to grant 473 | patent sublicenses in a manner consistent with the requirements of 474 | this License. 475 | 476 | Each contributor grants you a non-exclusive, worldwide, royalty-free 477 | patent license under the contributor's essential patent claims, to 478 | make, use, sell, offer for sale, import and otherwise run, modify and 479 | propagate the contents of its contributor version. 480 | 481 | In the following three paragraphs, a "patent license" is any express 482 | agreement or commitment, however denominated, not to enforce a patent 483 | (such as an express permission to practice a patent or covenant not to 484 | sue for patent infringement). To "grant" such a patent license to a 485 | party means to make such an agreement or commitment not to enforce a 486 | patent against the party. 487 | 488 | If you convey a covered work, knowingly relying on a patent license, 489 | and the Corresponding Source of the work is not available for anyone 490 | to copy, free of charge and under the terms of this License, through a 491 | publicly available network server or other readily accessible means, 492 | then you must either (1) cause the Corresponding Source to be so 493 | available, or (2) arrange to deprive yourself of the benefit of the 494 | patent license for this particular work, or (3) arrange, in a manner 495 | consistent with the requirements of this License, to extend the patent 496 | license to downstream recipients. "Knowingly relying" means you have 497 | actual knowledge that, but for the patent license, your conveying the 498 | covered work in a country, or your recipient's use of the covered work 499 | in a country, would infringe one or more identifiable patents in that 500 | country that you have reason to believe are valid. 501 | 502 | If, pursuant to or in connection with a single transaction or 503 | arrangement, you convey, or propagate by procuring conveyance of, a 504 | covered work, and grant a patent license to some of the parties 505 | receiving the covered work authorizing them to use, propagate, modify 506 | or convey a specific copy of the covered work, then the patent license 507 | you grant is automatically extended to all recipients of the covered 508 | work and works based on it. 509 | 510 | A patent license is "discriminatory" if it does not include within the 511 | scope of its coverage, prohibits the exercise of, or is conditioned on 512 | the non-exercise of one or more of the rights that are specifically 513 | granted under this License. You may not convey a covered work if you 514 | are a party to an arrangement with a third party that is in the 515 | business of distributing software, under which you make payment to the 516 | third party based on the extent of your activity of conveying the 517 | work, and under which the third party grants, to any of the parties 518 | who would receive the covered work from you, a discriminatory patent 519 | license (a) in connection with copies of the covered work conveyed by 520 | you (or copies made from those copies), or (b) primarily for and in 521 | connection with specific products or compilations that contain the 522 | covered work, unless you entered into that arrangement, or that patent 523 | license was granted, prior to 28 March 2007. 524 | 525 | Nothing in this License shall be construed as excluding or limiting 526 | any implied license or other defenses to infringement that may 527 | otherwise be available to you under applicable patent law. 528 | 529 | 12. No Surrender of Others' Freedom. 530 | 531 | If conditions are imposed on you (whether by court order, agreement or 532 | otherwise) that contradict the conditions of this License, they do not 533 | excuse you from the conditions of this License. If you cannot convey a 534 | covered work so as to satisfy simultaneously your obligations under 535 | this License and any other pertinent obligations, then as a 536 | consequence you may not convey it at all. For example, if you agree to 537 | terms that obligate you to collect a royalty for further conveying 538 | from those to whom you convey the Program, the only way you could 539 | satisfy both those terms and this License would be to refrain entirely 540 | from conveying the Program. 541 | 542 | 13. Remote Network Interaction; Use with the GNU General Public 543 | License. 544 | 545 | Notwithstanding any other provision of this License, if you modify the 546 | Program, your modified version must prominently offer all users 547 | interacting with it remotely through a computer network (if your 548 | version supports such interaction) an opportunity to receive the 549 | Corresponding Source of your version by providing access to the 550 | Corresponding Source from a network server at no charge, through some 551 | standard or customary means of facilitating copying of software. This 552 | Corresponding Source shall include the Corresponding Source for any 553 | work covered by version 3 of the GNU General Public License that is 554 | incorporated pursuant to the following paragraph. 555 | 556 | Notwithstanding any other provision of this License, you have 557 | permission to link or combine any covered work with a work licensed 558 | under version 3 of the GNU General Public License into a single 559 | combined work, and to convey the resulting work. The terms of this 560 | License will continue to apply to the part which is the covered work, 561 | but the work with which it is combined will remain governed by version 562 | 3 of the GNU General Public License. 563 | 564 | 14. Revised Versions of this License. 565 | 566 | The Free Software Foundation may publish revised and/or new versions 567 | of the GNU Affero General Public License from time to time. Such new 568 | versions will be similar in spirit to the present version, but may 569 | differ in detail to address new problems or concerns. 570 | 571 | Each version is given a distinguishing version number. If the Program 572 | specifies that a certain numbered version of the GNU Affero General 573 | Public License "or any later version" applies to it, you have the 574 | option of following the terms and conditions either of that numbered 575 | version or of any later version published by the Free Software 576 | Foundation. If the Program does not specify a version number of the 577 | GNU Affero General Public License, you may choose any version ever 578 | published by the Free Software Foundation. 579 | 580 | If the Program specifies that a proxy can decide which future versions 581 | of the GNU Affero General Public License can be used, that proxy's 582 | public statement of acceptance of a version permanently authorizes you 583 | to choose that version for the Program. 584 | 585 | Later license versions may give you additional or different 586 | permissions. However, no additional obligations are imposed on any 587 | author or copyright holder as a result of your choosing to follow a 588 | later version. 589 | 590 | 15. Disclaimer of Warranty. 591 | 592 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 593 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 594 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT 595 | WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT 596 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 597 | A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND 598 | PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE 599 | DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR 600 | CORRECTION. 601 | 602 | 16. Limitation of Liability. 603 | 604 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 605 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR 606 | CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 607 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES 608 | ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT 609 | NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR 610 | LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM 611 | TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER 612 | PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 613 | 614 | 17. Interpretation of Sections 15 and 16. 615 | 616 | If the disclaimer of warranty and limitation of liability provided 617 | above cannot be given local legal effect according to their terms, 618 | reviewing courts shall apply local law that most closely approximates 619 | an absolute waiver of all civil liability in connection with the 620 | Program, unless a warranty or assumption of liability accompanies a 621 | copy of the Program in return for a fee. 622 | 623 | END OF TERMS AND CONDITIONS 624 | 625 | How to Apply These Terms to Your New Programs 626 | 627 | If you develop a new program, and you want it to be of the greatest 628 | possible use to the public, the best way to achieve this is to make it 629 | free software which everyone can redistribute and change under these 630 | terms. 631 | 632 | To do so, attach the following notices to the program. It is safest to 633 | attach them to the start of each source file to most effectively state 634 | the exclusion of warranty; and each file should have at least the 635 | "copyright" line and a pointer to where the full notice is found. 636 | 637 | Copyright (C) 639 | 640 | This program is free software: you can redistribute it and/or 641 | modify it under the terms of the GNU Affero General Public License 642 | as published by the Free Software Foundation, either version 3 of 643 | the License, or (at your option) any later version. 644 | 645 | This program is distributed in the hope that it will be useful, 646 | but WITHOUT ANY WARRANTY; without even the implied warranty of 647 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 648 | Affero General Public License for more details. 649 | 650 | You should have received a copy of the GNU Affero General Public 651 | License along with this program. If not, see 652 | . Also add information on how to 653 | contact you by electronic and paper mail. 654 | 655 | If your software can interact with users remotely through a computer 656 | network, you should also make sure that it provides a way for users to 657 | get its source. For example, if your program is a web application, its 658 | interface could display a "Source" link that leads users to an archive 659 | of the code. There are many ways you could offer source, and different 660 | solutions will be better for different programs; see section 13 for 661 | the specific requirements. 662 | 663 | You should also get your employer (if you work as a programmer) or 664 | school, if any, to sign a "copyright disclaimer" for the program, if 665 | necessary. For more information on this, and how to apply and follow 666 | the GNU AGPL, see . -------------------------------------------------------------------------------- /tetgen.h: -------------------------------------------------------------------------------- 1 | //============================================================================// 2 | // // 3 | // TetGen // 4 | // // 5 | // A Quality Tetrahedral Mesh Generator and A 3D Delaunay Triangulator // 6 | // // 7 | // Version 1.6.0 // 8 | // August 31, 2020 // 9 | // // 10 | // Copyright (C) 2002--2020 // 11 | // // 12 | // Hang Si // 13 | // Research Group: Numerical Mathematics and Scientific Computing // 14 | // Weierstrass Institute for Applied Analysis and Stochastics (WIAS) // 15 | // Mohrenstr. 39, 10117 Berlin, Germany // 16 | // si@wias-berlin.de // 17 | // // 18 | // TetGen is a tetrahedral mesh generator. It creates 3d triangulations of // 19 | // polyhedral domains. It generates meshes with well-shaped elements whose // 20 | // sizes are adapted to the geometric features or user-provided sizing // 21 | // functions. It has applications in various applications in scientific // 22 | // computing, such as computer graphics (CG), computer-aided design (CAD), // 23 | // geometry processing (parametrizations and computer animation), and // 24 | // physical simulations (finite element analysis). // 25 | // // 26 | // TetGen computes (weighted) Delaunay triangulations for three-dimensional // 27 | // (weighted) point sets, and constrained Delaunay triangulations for // 28 | // three-dimensional polyhedral domains. In the latter case, input edges // 29 | // and triangles can be completely preserved in the output meshes. TetGen // 30 | // can refine or coarsen an existing mesh to result in good quality and // 31 | // size-adapted mesh according to the geometric features and user-defined // 32 | // mesh sizing functions. // 33 | // // 34 | // TetGen implements theoretically proven algorithms for computing the // 35 | // Delaunay and constrained Delaunay tetrahedralizations. TetGen achieves // 36 | // robustness and efficiency by using advanced techniques in computational // 37 | // geometry. A technical paper describes the algorithms and methods // 38 | // implemented in TetGen is available in ACM-TOMS, Hang Si ``TetGen, a // 39 | // Delaunay-Based Quality Tetrahedral Mesh Generator", ACM Transactions on // 40 | // Mathematical Software, February 2015, https://doi.org/10.1145/2629697. // 41 | // // 42 | // TetGen is freely available through the website: http://www.tetgen.org. // 43 | // It may be copied, modified, and redistributed for non-commercial use. // 44 | // Please consult the file LICENSE for the detailed copyright notices. // 45 | // // 46 | //============================================================================// 47 | 48 | 49 | #ifndef tetgenH 50 | #define tetgenH 51 | 52 | // To compile TetGen as a library instead of an executable program, define 53 | // the TETLIBRARY symbol. 54 | 55 | // #define TETLIBRARY 56 | 57 | 58 | // TetGen default uses the double-precision (64 bit) for a real number. 59 | // Alternatively, one can use the single-precision (32 bit) 'float' if the 60 | // memory is limited. 61 | 62 | #define REAL double // #define REAL float 63 | 64 | // The maximum number of characters in a file name (including the null). 65 | 66 | #define FILENAMESIZE 1024 67 | 68 | // The maximum number of chars in a line read from a file (including the null). 69 | 70 | #define INPUTLINESIZE 2048 71 | 72 | // C standard libraries to perform Input/output operations, general utililities, 73 | // manipulate strings and arrays, compute common mathematical operations, 74 | // get date and time information. 75 | 76 | #include 77 | #include 78 | #include 79 | #include 80 | #include 81 | 82 | // The types 'intptr_t' and 'uintptr_t' are signed and unsigned integer types, 83 | // respectively. They are guaranteed to be the same width as a pointer. 84 | // They are defined in by the C99 Standard. 85 | 86 | #include 87 | 88 | //============================================================================// 89 | // // 90 | // tetgenio // 91 | // // 92 | // A structure for transferring input/output data between the user and // 93 | // TetGen's internal data structure (class tetgenmesh). // 94 | // // 95 | // This data structure contains a collection of arrays, i.e., points, facets, // 96 | // tetrahedra. It contains functions to read input data from files (.node, // 97 | // .poly, .face, .edge, .ele) as well as write output data into files. // 98 | // // 99 | // Once an object of tetgenio is declared, no array is created. One has to // 100 | // allocate enough memory for them. On the deletion of this object, the // 101 | // memory occupied by these arrays needs to be freed. The routine // 102 | // deinitialize() will be automatically called. It frees the memory for // 103 | // an array if it is not a NULL. Note that it assumes that the memory is // 104 | // allocated by the C++ "new" operator. Otherwise, the user is responsible // 105 | // to free them and all pointers must be NULL. // 106 | // // 107 | //============================================================================// 108 | 109 | class tetgenio { 110 | 111 | public: 112 | 113 | // A "polygon" describes a simple polygon (no holes). It is not necessarily 114 | // convex. Each polygon contains a number of corners (points) and the same 115 | // number of sides (edges). The points of the polygon must be given in 116 | // either counterclockwise or clockwise order and they form a ring, so 117 | // every two consecutive points forms an edge of the polygon. 118 | typedef struct { 119 | int *vertexlist; 120 | int numberofvertices; 121 | } polygon; 122 | 123 | // A "facet" describes a polygonal region possibly with holes, edges, and 124 | // points floating in it. Each facet consists of a list of polygons and 125 | // a list of hole points (which lie strictly inside holes). 126 | typedef struct { 127 | polygon *polygonlist; 128 | int numberofpolygons; 129 | REAL *holelist; 130 | int numberofholes; 131 | } facet; 132 | 133 | // A "voroedge" is an edge of the Voronoi diagram. It corresponds to a 134 | // Delaunay face. Each voroedge is either a line segment connecting 135 | // two Voronoi vertices or a ray starting from a Voronoi vertex to an 136 | // "infinite vertex". 'v1' and 'v2' are two indices pointing to the 137 | // list of Voronoi vertices. 'v1' must be non-negative, while 'v2' may 138 | // be -1 if it is a ray, in this case, the unit normal of this ray is 139 | // given in 'vnormal'. 140 | typedef struct { 141 | int v1, v2; 142 | REAL vnormal[3]; 143 | } voroedge; 144 | 145 | // A "vorofacet" is an facet of the Voronoi diagram. It corresponds to a 146 | // Delaunay edge. Each Voronoi facet is a convex polygon formed by a 147 | // list of Voronoi edges, it may not be closed. 'c1' and 'c2' are two 148 | // indices pointing into the list of Voronoi cells, i.e., the two cells 149 | // share this facet. 'elist' is an array of indices pointing into the 150 | // list of Voronoi edges, 'elist[0]' saves the number of Voronoi edges 151 | // (including rays) of this facet. 152 | typedef struct { 153 | int c1, c2; 154 | int *elist; 155 | } vorofacet; 156 | 157 | 158 | // Additional parameters associated with an input (or mesh) vertex. 159 | // These informations are provided by CAD libraries. 160 | typedef struct { 161 | REAL uv[2]; 162 | int tag; 163 | int type; // 0, 1, or 2. 164 | } pointparam; 165 | 166 | // Callback functions for meshing PSCs. 167 | typedef REAL (* GetVertexParamOnEdge)(void*, int, int); 168 | typedef void (* GetSteinerOnEdge)(void*, int, REAL, REAL*); 169 | typedef void (* GetVertexParamOnFace)(void*, int, int, REAL*); 170 | typedef void (* GetEdgeSteinerParamOnFace)(void*, int, REAL, int, REAL*); 171 | typedef void (* GetSteinerOnFace)(void*, int, REAL*, REAL*); 172 | 173 | // A callback function for mesh refinement. 174 | typedef bool (* TetSizeFunc)(REAL*, REAL*, REAL*, REAL*, REAL*, REAL); 175 | 176 | // Items are numbered starting from 'firstnumber' (0 or 1), default is 0. 177 | int firstnumber; 178 | 179 | // Dimension of the mesh (2 or 3), default is 3. 180 | int mesh_dim; 181 | 182 | // Does the lines in .node file contain index or not, default is 1. 183 | int useindex; 184 | 185 | // 'pointlist': An array of point coordinates. The first point's x 186 | // coordinate is at index [0] and its y coordinate at index [1], its 187 | // z coordinate is at index [2], followed by the coordinates of the 188 | // remaining points. Each point occupies three REALs. 189 | // 'pointattributelist': An array of point attributes. Each point's 190 | // attributes occupy 'numberofpointattributes' REALs. 191 | // 'pointmtrlist': An array of metric tensors at points. Each point's 192 | // tensor occupies 'numberofpointmtr' REALs. 193 | // 'pointmarkerlist': An array of point markers; one integer per point. 194 | // 'point2tetlist': An array of tetrahedra indices; one integer per point. 195 | REAL *pointlist; 196 | REAL *pointattributelist; 197 | REAL *pointmtrlist; 198 | int *pointmarkerlist; 199 | int *point2tetlist; 200 | pointparam *pointparamlist; 201 | int numberofpoints; 202 | int numberofpointattributes; 203 | int numberofpointmtrs; 204 | 205 | // 'tetrahedronlist': An array of tetrahedron corners. The first 206 | // tetrahedron's first corner is at index [0], followed by its other 207 | // corners, followed by six nodes on the edges of the tetrahedron if the 208 | // second order option (-o2) is applied. Each tetrahedron occupies 209 | // 'numberofcorners' ints. The second order nodes are ouput only. 210 | // 'tetrahedronattributelist': An array of tetrahedron attributes. Each 211 | // tetrahedron's attributes occupy 'numberoftetrahedronattributes' REALs. 212 | // 'tetrahedronvolumelist': An array of constraints, i.e. tetrahedron's 213 | // volume; one REAL per element. Input only. 214 | // 'neighborlist': An array of tetrahedron neighbors; 4 ints per element. 215 | // 'tet2facelist': An array of tetrahedron face indices; 4 ints per element. 216 | // 'tet2edgelist': An array of tetrahedron edge indices; 6 ints per element. 217 | int *tetrahedronlist; 218 | REAL *tetrahedronattributelist; 219 | REAL *tetrahedronvolumelist; 220 | int *neighborlist; 221 | int *tet2facelist; 222 | int *tet2edgelist; 223 | int numberoftetrahedra; 224 | int numberofcorners; 225 | int numberoftetrahedronattributes; 226 | 227 | // 'facetlist': An array of facets. Each entry is a structure of facet. 228 | // 'facetmarkerlist': An array of facet markers; one int per facet. 229 | facet *facetlist; 230 | int *facetmarkerlist; 231 | int numberoffacets; 232 | 233 | // 'holelist': An array of holes (in volume). Each hole is given by a 234 | // seed (point) which lies strictly inside it. The first seed's x, y and z 235 | // coordinates are at indices [0], [1] and [2], followed by the 236 | // remaining seeds. Three REALs per hole. 237 | REAL *holelist; 238 | int numberofholes; 239 | 240 | // 'regionlist': An array of regions (subdomains). Each region is given by 241 | // a seed (point) which lies strictly inside it. The first seed's x, y and 242 | // z coordinates are at indices [0], [1] and [2], followed by the regional 243 | // attribute at index [3], followed by the maximum volume at index [4]. 244 | // Five REALs per region. 245 | // Note that each regional attribute is used only if you select the 'A' 246 | // switch, and each volume constraint is used only if you select the 247 | // 'a' switch (with no number following). 248 | REAL *regionlist; 249 | int numberofregions; 250 | 251 | // 'refine_elem_list': An array of tetrahedra to be refined. The first 252 | // tetrahedron's first corner is at index [0], followed by its other 253 | // corners. Four integers per element. 254 | // 'refine_elem_vol_list': An array of constraints, i.e. tetrahedron's 255 | // volume; one REAL per element. 256 | int *refine_elem_list; 257 | REAL *refine_elem_vol_list; 258 | int numberofrefineelems; 259 | 260 | // 'facetconstraintlist': An array of facet constraints. Each constraint 261 | // specifies a maximum area bound on the subfaces of that facet. The 262 | // first facet constraint is given by a facet marker at index [0] and its 263 | // maximum area bound at index [1], followed by the remaining facet con- 264 | // straints. Two REALs per facet constraint. Note: the facet marker is 265 | // actually an integer. 266 | REAL *facetconstraintlist; 267 | int numberoffacetconstraints; 268 | 269 | // 'segmentconstraintlist': An array of segment constraints. Each constraint 270 | // specifies a maximum length bound on the subsegments of that segment. 271 | // The first constraint is given by the two endpoints of the segment at 272 | // index [0] and [1], and the maximum length bound at index [2], followed 273 | // by the remaining segment constraints. Three REALs per constraint. 274 | // Note the segment endpoints are actually integers. 275 | REAL *segmentconstraintlist; 276 | int numberofsegmentconstraints; 277 | 278 | 279 | // 'trifacelist': An array of face (triangle) corners. The first face's 280 | // three corners are at indices [0], [1] and [2], followed by the remaining 281 | // faces. Three ints per face. 282 | // 'trifacemarkerlist': An array of face markers; one int per face. 283 | // 'o2facelist': An array of second order nodes (on the edges) of the face. 284 | // It is output only if the second order option (-o2) is applied. The 285 | // first face's three second order nodes are at [0], [1], and [2], 286 | // followed by the remaining faces. Three ints per face. 287 | // 'face2tetlist': An array of tetrahedra indices; 2 ints per face. 288 | // 'face2edgelist': An array of edge indices; 3 ints per face. 289 | int *trifacelist; 290 | int *trifacemarkerlist; 291 | int *o2facelist; 292 | int *face2tetlist; 293 | int *face2edgelist; 294 | int numberoftrifaces; 295 | 296 | // 'edgelist': An array of edge endpoints. The first edge's endpoints 297 | // are at indices [0] and [1], followed by the remaining edges. 298 | // Two ints per edge. 299 | // 'edgemarkerlist': An array of edge markers; one int per edge. 300 | // 'o2edgelist': An array of midpoints of edges. It is output only if the 301 | // second order option (-o2) is applied. One int per edge. 302 | // 'edge2tetlist': An array of tetrahedra indices. One int per edge. 303 | int *edgelist; 304 | int *edgemarkerlist; 305 | int *o2edgelist; 306 | int *edge2tetlist; 307 | int numberofedges; 308 | 309 | // 'vpointlist': An array of Voronoi vertex coordinates (like pointlist). 310 | // 'vedgelist': An array of Voronoi edges. Each entry is a 'voroedge'. 311 | // 'vfacetlist': An array of Voronoi facets. Each entry is a 'vorofacet'. 312 | // 'vcelllist': An array of Voronoi cells. Each entry is an array of 313 | // indices pointing into 'vfacetlist'. The 0th entry is used to store 314 | // the length of this array. 315 | REAL *vpointlist; 316 | voroedge *vedgelist; 317 | vorofacet *vfacetlist; 318 | int **vcelllist; 319 | int numberofvpoints; 320 | int numberofvedges; 321 | int numberofvfacets; 322 | int numberofvcells; 323 | 324 | 325 | // Variable (and callback functions) for meshing PSCs. 326 | void *geomhandle; 327 | GetVertexParamOnEdge getvertexparamonedge; 328 | GetSteinerOnEdge getsteineronedge; 329 | GetVertexParamOnFace getvertexparamonface; 330 | GetEdgeSteinerParamOnFace getedgesteinerparamonface; 331 | GetSteinerOnFace getsteineronface; 332 | 333 | // A callback function. 334 | TetSizeFunc tetunsuitable; 335 | 336 | // Input & output routines. 337 | bool load_node_call(FILE* infile, int markers, int uvflag, char*); 338 | bool load_node(char*); 339 | bool load_edge(char*); 340 | bool load_face(char*); 341 | bool load_tet(char*); 342 | bool load_vol(char*); 343 | bool load_var(char*); 344 | bool load_mtr(char*); 345 | bool load_elem(char*); 346 | bool load_poly(char*); 347 | bool load_off(char*); 348 | bool load_ply(char*); 349 | bool load_stl(char*); 350 | bool load_vtk(char*); 351 | bool load_medit(char*, int); 352 | bool load_neumesh(char*, int); 353 | bool load_plc(char*, int); 354 | bool load_tetmesh(char*, int); 355 | void save_nodes(const char*); 356 | void save_elements(const char*); 357 | void save_faces(const char*); 358 | void save_edges(char*); 359 | void save_neighbors(char*); 360 | void save_poly(const char*); 361 | void save_faces2smesh(char*); 362 | 363 | // Read line and parse string functions. 364 | char *readline(char* string, FILE* infile, int *linenumber); 365 | char *findnextfield(char* string); 366 | char *readnumberline(char* string, FILE* infile, char* infilename); 367 | char *findnextnumber(char* string); 368 | 369 | static void init(polygon* p) { 370 | p->vertexlist = (int *) NULL; 371 | p->numberofvertices = 0; 372 | } 373 | 374 | static void init(facet* f) { 375 | f->polygonlist = (polygon *) NULL; 376 | f->numberofpolygons = 0; 377 | f->holelist = (REAL *) NULL; 378 | f->numberofholes = 0; 379 | } 380 | 381 | // Initialize routine. 382 | void initialize() 383 | { 384 | firstnumber = 0; 385 | mesh_dim = 3; 386 | useindex = 1; 387 | 388 | pointlist = (REAL *) NULL; 389 | pointattributelist = (REAL *) NULL; 390 | pointmtrlist = (REAL *) NULL; 391 | pointmarkerlist = (int *) NULL; 392 | point2tetlist = (int *) NULL; 393 | pointparamlist = (pointparam *) NULL; 394 | numberofpoints = 0; 395 | numberofpointattributes = 0; 396 | numberofpointmtrs = 0; 397 | 398 | tetrahedronlist = (int *) NULL; 399 | tetrahedronattributelist = (REAL *) NULL; 400 | tetrahedronvolumelist = (REAL *) NULL; 401 | neighborlist = (int *) NULL; 402 | tet2facelist = (int *) NULL; 403 | tet2edgelist = (int *) NULL; 404 | numberoftetrahedra = 0; 405 | numberofcorners = 4; 406 | numberoftetrahedronattributes = 0; 407 | 408 | trifacelist = (int *) NULL; 409 | trifacemarkerlist = (int *) NULL; 410 | o2facelist = (int *) NULL; 411 | face2tetlist = (int *) NULL; 412 | face2edgelist = (int *) NULL; 413 | numberoftrifaces = 0; 414 | 415 | edgelist = (int *) NULL; 416 | edgemarkerlist = (int *) NULL; 417 | o2edgelist = (int *) NULL; 418 | edge2tetlist = (int *) NULL; 419 | numberofedges = 0; 420 | 421 | facetlist = (facet *) NULL; 422 | facetmarkerlist = (int *) NULL; 423 | numberoffacets = 0; 424 | 425 | holelist = (REAL *) NULL; 426 | numberofholes = 0; 427 | 428 | regionlist = (REAL *) NULL; 429 | numberofregions = 0; 430 | 431 | refine_elem_list = (int *) NULL; 432 | refine_elem_vol_list = (REAL *) NULL; 433 | numberofrefineelems = 0; 434 | 435 | facetconstraintlist = (REAL *) NULL; 436 | numberoffacetconstraints = 0; 437 | segmentconstraintlist = (REAL *) NULL; 438 | numberofsegmentconstraints = 0; 439 | 440 | 441 | vpointlist = (REAL *) NULL; 442 | vedgelist = (voroedge *) NULL; 443 | vfacetlist = (vorofacet *) NULL; 444 | vcelllist = (int **) NULL; 445 | numberofvpoints = 0; 446 | numberofvedges = 0; 447 | numberofvfacets = 0; 448 | numberofvcells = 0; 449 | 450 | 451 | tetunsuitable = NULL; 452 | 453 | geomhandle = NULL; 454 | getvertexparamonedge = NULL; 455 | getsteineronedge = NULL; 456 | getvertexparamonface = NULL; 457 | getedgesteinerparamonface = NULL; 458 | getsteineronface = NULL; 459 | } 460 | 461 | // Free the memory allocated in 'tetgenio'. Note that it assumes that the 462 | // memory was allocated by the "new" operator (C++). 463 | void clean_memory() 464 | { 465 | int i, j; 466 | 467 | if (pointlist != (REAL *) NULL) { 468 | delete [] pointlist; 469 | } 470 | if (pointattributelist != (REAL *) NULL) { 471 | delete [] pointattributelist; 472 | } 473 | if (pointmtrlist != (REAL *) NULL) { 474 | delete [] pointmtrlist; 475 | } 476 | if (pointmarkerlist != (int *) NULL) { 477 | delete [] pointmarkerlist; 478 | } 479 | if (point2tetlist != (int *) NULL) { 480 | delete [] point2tetlist; 481 | } 482 | if (pointparamlist != (pointparam *) NULL) { 483 | delete [] pointparamlist; 484 | } 485 | 486 | if (tetrahedronlist != (int *) NULL) { 487 | delete [] tetrahedronlist; 488 | } 489 | if (tetrahedronattributelist != (REAL *) NULL) { 490 | delete [] tetrahedronattributelist; 491 | } 492 | if (tetrahedronvolumelist != (REAL *) NULL) { 493 | delete [] tetrahedronvolumelist; 494 | } 495 | if (neighborlist != (int *) NULL) { 496 | delete [] neighborlist; 497 | } 498 | if (tet2facelist != (int *) NULL) { 499 | delete [] tet2facelist; 500 | } 501 | if (tet2edgelist != (int *) NULL) { 502 | delete [] tet2edgelist; 503 | } 504 | 505 | if (trifacelist != (int *) NULL) { 506 | delete [] trifacelist; 507 | } 508 | if (trifacemarkerlist != (int *) NULL) { 509 | delete [] trifacemarkerlist; 510 | } 511 | if (o2facelist != (int *) NULL) { 512 | delete [] o2facelist; 513 | } 514 | if (face2tetlist != (int *) NULL) { 515 | delete [] face2tetlist; 516 | } 517 | if (face2edgelist != (int *) NULL) { 518 | delete [] face2edgelist; 519 | } 520 | 521 | if (edgelist != (int *) NULL) { 522 | delete [] edgelist; 523 | } 524 | if (edgemarkerlist != (int *) NULL) { 525 | delete [] edgemarkerlist; 526 | } 527 | if (o2edgelist != (int *) NULL) { 528 | delete [] o2edgelist; 529 | } 530 | if (edge2tetlist != (int *) NULL) { 531 | delete [] edge2tetlist; 532 | } 533 | 534 | if (facetlist != (facet *) NULL) { 535 | facet *f; 536 | polygon *p; 537 | for (i = 0; i < numberoffacets; i++) { 538 | f = &facetlist[i]; 539 | for (j = 0; j < f->numberofpolygons; j++) { 540 | p = &f->polygonlist[j]; 541 | delete [] p->vertexlist; 542 | } 543 | delete [] f->polygonlist; 544 | if (f->holelist != (REAL *) NULL) { 545 | delete [] f->holelist; 546 | } 547 | } 548 | delete [] facetlist; 549 | } 550 | if (facetmarkerlist != (int *) NULL) { 551 | delete [] facetmarkerlist; 552 | } 553 | 554 | if (holelist != (REAL *) NULL) { 555 | delete [] holelist; 556 | } 557 | if (regionlist != (REAL *) NULL) { 558 | delete [] regionlist; 559 | } 560 | if (refine_elem_list != (int *) NULL) { 561 | delete [] refine_elem_list; 562 | if (refine_elem_vol_list != (REAL *) NULL) { 563 | delete [] refine_elem_vol_list; 564 | } 565 | } 566 | if (facetconstraintlist != (REAL *) NULL) { 567 | delete [] facetconstraintlist; 568 | } 569 | if (segmentconstraintlist != (REAL *) NULL) { 570 | delete [] segmentconstraintlist; 571 | } 572 | if (vpointlist != (REAL *) NULL) { 573 | delete [] vpointlist; 574 | } 575 | if (vedgelist != (voroedge *) NULL) { 576 | delete [] vedgelist; 577 | } 578 | if (vfacetlist != (vorofacet *) NULL) { 579 | for (i = 0; i < numberofvfacets; i++) { 580 | delete [] vfacetlist[i].elist; 581 | } 582 | delete [] vfacetlist; 583 | } 584 | if (vcelllist != (int **) NULL) { 585 | for (i = 0; i < numberofvcells; i++) { 586 | delete [] vcelllist[i]; 587 | } 588 | delete [] vcelllist; 589 | } 590 | } 591 | 592 | // Constructor & destructor. 593 | tetgenio() {initialize();} 594 | ~tetgenio() {clean_memory();} 595 | 596 | }; // class tetgenio 597 | 598 | //============================================================================// 599 | // // 600 | // tetgenbehavior // 601 | // // 602 | // A structure for maintaining the switches and parameters used by TetGen's // 603 | // internal data structure and algorithms. // 604 | // // 605 | // All switches and parameters are initialized with default values. They are // 606 | // set by the command line arguments (argc, argv). // 607 | // // 608 | // NOTE: Some switches are incompatible with others. While some may depend // 609 | // on other switches. The routine parse_commandline() sets the switches from // 610 | // the command line (a list of strings) and checks the consistency of the // 611 | // applied switches. // 612 | // // 613 | //============================================================================// 614 | 615 | class tetgenbehavior { 616 | 617 | public: 618 | 619 | // Switches of TetGen. 620 | int plc; // '-p', 0. 621 | int psc; // '-s', 0. 622 | int refine; // '-r', 0. 623 | int quality; // '-q', 0. 624 | int nobisect; // '-Y', 0. 625 | int cdt; // '-D', 0. 626 | int cdtrefine; // '-D#', 7. 627 | int coarsen; // '-R', 0. 628 | int weighted; // '-w', 0. 629 | int brio_hilbert; // '-b', 1. 630 | int flipinsert; // '-L', 0. 631 | int metric; // '-m', 0. 632 | int varvolume; // '-a', 0. 633 | int fixedvolume; // '-a', 0. 634 | int regionattrib; // '-A', 0. 635 | int insertaddpoints; // '-i', 0. 636 | int diagnose; // '-d', 0. 637 | int convex; // '-c', 0. 638 | int nomergefacet; // '-M', 0. 639 | int nomergevertex; // '-M', 0. 640 | int noexact; // '-X', 0. 641 | int nostaticfilter; // '-X', 0. 642 | int zeroindex; // '-z', 0. 643 | int facesout; // '-f', 0. 644 | int edgesout; // '-e', 0. 645 | int neighout; // '-n', 0. 646 | int voroout; // '-v', 0. 647 | int meditview; // '-g', 0. 648 | int vtkview; // '-k', 0. 649 | int vtksurfview; // '-k', 0. 650 | int nobound; // '-B', 0. 651 | int nonodewritten; // '-N', 0. 652 | int noelewritten; // '-E', 0. 653 | int nofacewritten; // '-F', 0. 654 | int noiterationnum; // '-I', 0. 655 | int nojettison; // '-J', 0. 656 | int docheck; // '-C', 0. 657 | int quiet; // '-Q', 0. 658 | int nowarning; // '-W', 0. 659 | int verbose; // '-V', 0. 660 | 661 | // Parameters of TetGen. 662 | int vertexperblock; // '-x', 4092. 663 | int tetrahedraperblock; // '-x', 8188. 664 | int shellfaceperblock; // '-x', 2044. 665 | int supsteiner_level; // '-Y/', 2. 666 | int addsteiner_algo; // '-Y//', 1. 667 | int coarsen_param; // '-R', 0. 668 | int weighted_param; // '-w', 0. 669 | int fliplinklevel; // -1. 670 | int flipstarsize; // -1. 671 | int fliplinklevelinc; // 1. 672 | int opt_max_flip_level; // '-O', 3. 673 | int opt_scheme; // '-O/#', 7. 674 | int opt_iterations; // -O//#, 3. 675 | int smooth_cirterion; // -s, 1. 676 | int smooth_maxiter; // -s, 7. 677 | int delmaxfliplevel; // 1. 678 | int order; // '-o', 1. 679 | int reversetetori; // '-o/', 0. 680 | int steinerleft; // '-S', 0. 681 | int unflip_queue_limit; // '-U#', 1000. 682 | int no_sort; // 0. 683 | int hilbert_order; // '-b///', 52. 684 | int hilbert_limit; // '-b//' 8. 685 | int brio_threshold; // '-b' 64. 686 | REAL brio_ratio; // '-b/' 0.125. 687 | REAL epsilon; // '-T', 1.0e-8. 688 | REAL facet_separate_ang_tol; // '-p', 179.9. 689 | REAL collinear_ang_tol; // '-p/', 179.9. 690 | REAL facet_small_ang_tol; // '-p//', 15.0. 691 | REAL maxvolume; // '-a', -1.0. 692 | REAL maxvolume_length; // '-a', -1.0. 693 | REAL minratio; // '-q', 0.0. 694 | REAL opt_max_asp_ratio; // 1000.0. 695 | REAL opt_max_edge_ratio; // 100.0. 696 | REAL mindihedral; // '-q', 5.0. 697 | REAL optmaxdihedral; // -o/# 177.0. 698 | REAL metric_scale; // -m#, 1.0. 699 | REAL smooth_alpha; // '-s', 0.3. 700 | REAL coarsen_percent; // -R1/#, 1.0. 701 | REAL elem_growth_ratio; // Growth ratio of # elements, -r#, 0.0. 702 | REAL refine_progress_ratio; // -r/#, 0.333. 703 | 704 | // Strings of command line arguments and input/output file names. 705 | char commandline[1024]; 706 | char infilename[1024]; 707 | char outfilename[1024]; 708 | char addinfilename[1024]; 709 | char bgmeshfilename[1024]; 710 | 711 | // Read an additional tetrahedral mesh and treat it as holes [2018-07-30]. 712 | int hole_mesh; // '-H', 0. 713 | char hole_mesh_filename[1024]; 714 | 715 | // The input object of TetGen. They are recognized by either the input 716 | // file extensions or by the specified options. 717 | // Currently the following objects are supported: 718 | // - NODES, a list of nodes (.node); 719 | // - POLY, a piecewise linear complex (.poly or .smesh); 720 | // - OFF, a polyhedron (.off, Geomview's file format); 721 | // - PLY, a polyhedron (.ply, file format from gatech, only ASCII); 722 | // - STL, a surface mesh (.stl, stereolithography format); 723 | // - MEDIT, a surface mesh (.mesh, Medit's file format); 724 | // - MESH, a tetrahedral mesh (.ele). 725 | // If no extension is available, the imposed command line switch 726 | // (-p or -r) implies the object. 727 | enum objecttype {NODES, POLY, OFF, PLY, STL, MEDIT, VTK, MESH, NEU_MESH} object; 728 | 729 | 730 | void syntax(); 731 | void usage(); 732 | 733 | // Command line parse routine. 734 | bool parse_commandline(int argc, char **argv); 735 | bool parse_commandline(char *switches) { 736 | return parse_commandline(0, &switches); 737 | } 738 | 739 | // Initialize all variables. 740 | tetgenbehavior() 741 | { 742 | plc = 0; 743 | psc = 0; 744 | refine = 0; 745 | quality = 0; 746 | nobisect = 0; 747 | cdt = 0; // set by -D (without a number following it) 748 | cdtrefine = 7; // default, set by -D# 749 | coarsen = 0; 750 | metric = 0; 751 | weighted = 0; 752 | brio_hilbert = 1; 753 | flipinsert = 0; 754 | varvolume = 0; 755 | fixedvolume = 0; 756 | noexact = 0; 757 | nostaticfilter = 0; 758 | insertaddpoints = 0; 759 | regionattrib = 0; 760 | diagnose = 0; 761 | convex = 0; 762 | zeroindex = 0; 763 | facesout = 0; 764 | edgesout = 0; 765 | neighout = 0; 766 | voroout = 0; 767 | meditview = 0; 768 | vtkview = 0; 769 | vtksurfview = 0; 770 | nobound = 0; 771 | nonodewritten = 0; 772 | noelewritten = 0; 773 | nofacewritten = 0; 774 | noiterationnum = 0; 775 | nomergefacet = 0; 776 | nomergevertex = 0; 777 | nojettison = 0; 778 | docheck = 0; 779 | quiet = 0; 780 | nowarning = 0; 781 | verbose = 0; 782 | 783 | vertexperblock = 4092; 784 | tetrahedraperblock = 8188; 785 | shellfaceperblock = 4092; 786 | supsteiner_level = 2; 787 | addsteiner_algo = 1; 788 | coarsen_param = 0; 789 | weighted_param = 0; 790 | fliplinklevel = -1; 791 | flipstarsize = -1; 792 | fliplinklevelinc = 1; 793 | opt_scheme = 7; 794 | opt_max_flip_level = 3; 795 | opt_iterations = 3; 796 | delmaxfliplevel = 1; 797 | order = 1; 798 | reversetetori = 0; 799 | steinerleft = -1; 800 | unflip_queue_limit = 1000; 801 | no_sort = 0; 802 | hilbert_order = 52; //-1; 803 | hilbert_limit = 8; 804 | brio_threshold = 64; 805 | brio_ratio = 0.125; 806 | facet_separate_ang_tol = 179.9; 807 | collinear_ang_tol = 179.9; 808 | facet_small_ang_tol = 15.0; 809 | maxvolume = -1.0; 810 | maxvolume_length = -1.0; 811 | minratio = 2.0; 812 | opt_max_asp_ratio = 1000.; 813 | opt_max_edge_ratio = 100.; 814 | mindihedral = 3.5; 815 | optmaxdihedral = 177.00; 816 | epsilon = 1.0e-8; 817 | coarsen_percent = 1.0; 818 | metric_scale = 1.0; // -m# 819 | elem_growth_ratio = 0.0; // -r# 820 | refine_progress_ratio = 0.333; // -r/# 821 | object = NODES; 822 | 823 | smooth_cirterion = 3; // -s# default smooth surface and volume vertices. 824 | smooth_maxiter = 7; // set by -s#/7 825 | smooth_alpha = 0.3; // relax parameter, set by -s#/#/0.3 826 | 827 | commandline[0] = '\0'; 828 | infilename[0] = '\0'; 829 | outfilename[0] = '\0'; 830 | addinfilename[0] = '\0'; 831 | bgmeshfilename[0] = '\0'; 832 | 833 | hole_mesh = 0; 834 | hole_mesh_filename[0] = '\0'; 835 | 836 | } 837 | 838 | }; // class tetgenbehavior 839 | 840 | //============================================================================// 841 | // // 842 | // Robust Geometric predicates // 843 | // // 844 | // The following routines are the robust geometric predicates for orientation // 845 | // test and point-in-sphere test implemented by Jonathan Shewchuk. // 846 | // He generously provided the source code in the public domain, // 847 | // http://www.cs.cmu.edu/~quake/robust.html. // 848 | // predicates.cxx is a C++ version of the original C code. // 849 | // // 850 | // The original predicates of Shewchuk only use "dynamic filters", i.e., it // 851 | // computes the error at runtime step by step. TetGen first uses a "static // 852 | // filter" in each predicate. It estimates the maximal possible error in all // 853 | // cases. It safely and quickly "filters" many easy cases. // 854 | // // 855 | //============================================================================// 856 | 857 | void exactinit(int, int, int, REAL, REAL, REAL); 858 | 859 | REAL orient3d(REAL *pa, REAL *pb, REAL *pc, REAL *pd); 860 | REAL insphere(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe); 861 | REAL orient4d(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe, 862 | REAL ah, REAL bh, REAL ch, REAL dh, REAL eh); 863 | 864 | REAL orient2dexact(REAL *pa, REAL *pb, REAL *pc); 865 | REAL orient3dexact(REAL *pa, REAL *pb, REAL *pc, REAL *pd); 866 | REAL orient4dexact(REAL* pa, REAL* pb, REAL* pc, REAL* pd, REAL* pe, 867 | REAL ah, REAL bh, REAL ch, REAL dh, REAL eh); 868 | 869 | 870 | //============================================================================// 871 | // // 872 | // tetgenmesh TetGen's internal mesh data structure. // 873 | // // 874 | // It uses a tetrahedron-based mesh data structure. It implements elementary // 875 | // flip operations to locally modify the mesh. It implements basic meshing // 876 | // algorithms to create Delaunay tetrahedraliations, to perform boundary // 877 | // recovery, to place Steiner points in the mesh domain, and to optimize the // 878 | // quality of the mesh. // 879 | // // 880 | //============================================================================// 881 | 882 | class tetgenmesh { 883 | 884 | public: 885 | 886 | //============================================================================// 887 | // // 888 | // Mesh data structure // 889 | // // 890 | // A tetrahedral mesh T of a 3D piecewise linear complex (PLC) X is a 3D // 891 | // simplicial complex whose underlying space is equal to the space of X. T // 892 | // contains a 2D subcomplex S which is a triangular mesh of the boundary of // 893 | // X. S contains a 1D subcomplex L which is a linear mesh of the boundary of // 894 | // S. Faces and edges in S and L are respectively called subfaces and segme- // 895 | // nts to distinguish them from others in T. // 896 | // // 897 | // TetGen uses a tetrahedron-based data structure. It stores tetrahedra and // 898 | // vertices. This data structure is pointer-based. Each tetrahedron contains // 899 | // pointers to its vertices and adjacent tetrahedra. Each vertex holds its x-,// 900 | // y-, z-coordinates, and a pointer to one of the tetrahedra having it. Both // 901 | // tetrahedra and vertices may contain user data. // 902 | // // 903 | // Let T be a tetrahedralization. Each triangular face of T belongs to either // 904 | // two or one tetrahedron. In the latter case, it is an exterior boundary // 905 | // face of T. TetGen attaches tetrahedra (one-to-one) to such faces. All such // 906 | // tetrahedra contain an "infinite vertex" (which has no geometric coordinates// 907 | // ). One can imagine such a vertex lies in 4D space and is visible by all // 908 | // exterior boundary faces simultaneously. This extended set of tetrahedra // 909 | // (including the infinite vertex) becomes a tetrahedralization of a 3-sphere // 910 | // that has no boundary in 3d. It has the nice property that every triangular // 911 | // face is shared by exactly two tetrahedra. // 912 | // // 913 | // The current version of TetGen stores explicitly the subfaces and segments // 914 | // (which are in surface mesh S and the linear mesh L), respectively. Extra // 915 | // pointers are allocated in tetrahedra and subfaces to point each other. // 916 | // // 917 | //============================================================================// 918 | 919 | // The tetrahedron data structure. It includes the following fields: 920 | // - a list of four adjoining tetrahedra; 921 | // - a list of four vertices; 922 | // - a pointer to a list of four subfaces (optional, for -p switch); 923 | // - a pointer to a list of six segments (optional, for -p switch); 924 | // - a list of user-defined floating-point attributes (optional); 925 | // - a volume constraint (optional, for -a switch); 926 | // - an integer of element marker (and flags); 927 | // The structure of a tetrahedron is an array of pointers. Its actual size 928 | // (the length of the array) is determined at runtime. 929 | 930 | typedef REAL **tetrahedron; 931 | 932 | // The subface data structure. It includes the following fields: 933 | // - a list of three adjoining subfaces; 934 | // - a list of three vertices; 935 | // - a list of three adjoining segments; 936 | // - two adjoining tetrahedra; 937 | // - an area constraint (optional, for -q switch); 938 | // - an integer for boundary marker; 939 | // - an integer for type, flags, etc. 940 | 941 | typedef REAL **shellface; 942 | 943 | // The point data structure. It includes the following fields: 944 | // - x, y and z coordinates; 945 | // - a list of user-defined point attributes (optional); 946 | // - u, v coordinates (optional, for -s switch); 947 | // - a metric tensor (optional, for -q or -m switch); 948 | // - a pointer to an adjacent tetrahedron; 949 | // - a pointer to a parent (or a duplicate) point; 950 | // - a pointer to an adjacent subface or segment (optional, -p switch); 951 | // - a pointer to a tet in background mesh (optional, for -m switch); 952 | // - an integer for boundary marker (point index); 953 | // - an integer for point type (and flags). 954 | // - an integer for geometry tag (optional, for -s switch). 955 | // The structure of a point is an array of REALs. Its acutal size is 956 | // determined at the runtime. 957 | 958 | typedef REAL *point; 959 | 960 | //============================================================================// 961 | // // 962 | // Handles // 963 | // // 964 | // Navigation and manipulation in a tetrahedralization are accomplished by // 965 | // operating on structures referred as ``handles". A handle is a pair (t,v), // 966 | // where t is a pointer to a tetrahedron, and v is a 4-bit integer, in the // 967 | // range from 0 to 11. v is called the ``version'' of a tetrahedron, it rep- // 968 | // resents a directed edge of a specific face of the tetrahedron. // 969 | // // 970 | // There are 12 even permutations of the four vertices, each of them corres- // 971 | // ponds to a directed edge (a version) of the tetrahedron. The 12 versions // 972 | // can be grouped into 4 distinct ``edge rings'' in 4 ``oriented faces'' of // 973 | // this tetrahedron. One can encode each version (a directed edge) into a // 974 | // 4-bit integer such that the two upper bits encode the index (from 0 to 2) // 975 | // of this edge in the edge ring, and the two lower bits encode the index ( // 976 | // from 0 to 3) of the oriented face which contains this edge. // 977 | // // 978 | // The four vertices of a tetrahedron are indexed from 0 to 3 (according to // 979 | // their storage in the data structure). Give each face the same index as // 980 | // the node opposite it in the tetrahedron. Denote the edge connecting face // 981 | // i to face j as i/j. We number the twelve versions as follows: // 982 | // // 983 | // | edge 0 edge 1 edge 2 // 984 | // --------|-------------------------------- // 985 | // face 0 | 0 (0/1) 4 (0/3) 8 (0/2) // 986 | // face 1 | 1 (1/2) 5 (1/3) 9 (1/0) // 987 | // face 2 | 2 (2/3) 6 (2/1) 10 (2/0) // 988 | // face 3 | 3 (3/0) 7 (3/1) 11 (3/2) // 989 | // // 990 | // Similarly, navigation and manipulation in a (boundary) triangulation are // 991 | // done by using handles of triangles. Each handle is a pair (s, v), where s // 992 | // is a pointer to a triangle, and v is a version in the range from 0 to 5. // 993 | // Each version corresponds to a directed edge of this triangle. // 994 | // // 995 | // Number the three vertices of a triangle from 0 to 2 (according to their // 996 | // storage in the data structure). Give each edge the same index as the node // 997 | // opposite it in the triangle. The six versions of a triangle are: // 998 | // // 999 | // | edge 0 edge 1 edge 2 // 1000 | // ---------------|-------------------------- // 1001 | // ccw orieation | 0 2 4 // 1002 | // cw orieation | 1 3 5 // 1003 | // // 1004 | // In the following, a 'triface' is a handle of tetrahedron, and a 'face' is // 1005 | // a handle of a triangle. // 1006 | // // 1007 | //============================================================================// 1008 | 1009 | class triface { 1010 | public: 1011 | tetrahedron *tet; 1012 | int ver; // Range from 0 to 11. 1013 | triface() : tet(0), ver(0) {} 1014 | triface& operator=(const triface& t) { 1015 | tet = t.tet; ver = t.ver; 1016 | return *this; 1017 | } 1018 | }; 1019 | 1020 | class face { 1021 | public: 1022 | shellface *sh; 1023 | int shver; // Range from 0 to 5. 1024 | face() : sh(0), shver(0) {} 1025 | face& operator=(const face& s) { 1026 | sh = s.sh; shver = s.shver; 1027 | return *this; 1028 | } 1029 | }; 1030 | 1031 | //============================================================================// 1032 | // // 1033 | // Arraypool // 1034 | // // 1035 | // A dynamic linear array. (It is written by J. Shewchuk) // 1036 | // // 1037 | // Each arraypool contains an array of pointers to a number of blocks. Each // 1038 | // block contains the same fixed number of objects. Each index of the array // 1039 | // addresses a particular object in the pool. The most significant bits add- // 1040 | // ress the index of the block containing the object. The less significant // 1041 | // bits address this object within the block. // 1042 | // // 1043 | // 'objectbytes' is the size of one object in blocks; 'log2objectsperblock' // 1044 | // is the base-2 logarithm of 'objectsperblock'; 'objects' counts the number // 1045 | // of allocated objects; 'totalmemory' is the total memory in bytes. // 1046 | // // 1047 | //============================================================================// 1048 | 1049 | class arraypool { 1050 | 1051 | public: 1052 | 1053 | int objectbytes; 1054 | int objectsperblock; 1055 | int log2objectsperblock; 1056 | int objectsperblockmark; 1057 | int toparraylen; 1058 | char **toparray; 1059 | long objects; 1060 | unsigned long totalmemory; 1061 | 1062 | void restart(); 1063 | void poolinit(int sizeofobject, int log2objperblk); 1064 | char* getblock(int objectindex); 1065 | void* lookup(int objectindex); 1066 | int newindex(void **newptr); 1067 | 1068 | arraypool(int sizeofobject, int log2objperblk); 1069 | ~arraypool(); 1070 | }; 1071 | 1072 | // fastlookup() -- A fast, unsafe operation. Return the pointer to the object 1073 | // with a given index. Note: The object's block must have been allocated, 1074 | // i.e., by the function newindex(). 1075 | 1076 | #define fastlookup(pool, index) \ 1077 | (void *) ((pool)->toparray[(index) >> (pool)->log2objectsperblock] + \ 1078 | ((index) & (pool)->objectsperblockmark) * (pool)->objectbytes) 1079 | 1080 | //============================================================================// 1081 | // // 1082 | // Memorypool // 1083 | // // 1084 | // A structure for memory allocation. (It is written by J. Shewchuk) // 1085 | // // 1086 | // firstblock is the first block of items. nowblock is the block from which // 1087 | // items are currently being allocated. nextitem points to the next slab // 1088 | // of free memory for an item. deaditemstack is the head of a linked list // 1089 | // (stack) of deallocated items that can be recycled. unallocateditems is // 1090 | // the number of items that remain to be allocated from nowblock. // 1091 | // // 1092 | // Traversal is the process of walking through the entire list of items, and // 1093 | // is separate from allocation. Note that a traversal will visit items on // 1094 | // the "deaditemstack" stack as well as live items. pathblock points to // 1095 | // the block currently being traversed. pathitem points to the next item // 1096 | // to be traversed. pathitemsleft is the number of items that remain to // 1097 | // be traversed in pathblock. // 1098 | // // 1099 | //============================================================================// 1100 | 1101 | class memorypool { 1102 | 1103 | public: 1104 | 1105 | void **firstblock, **nowblock; 1106 | void *nextitem; 1107 | void *deaditemstack; 1108 | void **pathblock; 1109 | void *pathitem; 1110 | int alignbytes; 1111 | int itembytes, itemwords; 1112 | int itemsperblock; 1113 | long items, maxitems; 1114 | int unallocateditems; 1115 | int pathitemsleft; 1116 | 1117 | memorypool(); 1118 | memorypool(int, int, int, int); 1119 | ~memorypool(); 1120 | 1121 | void poolinit(int, int, int, int); 1122 | void restart(); 1123 | void *alloc(); 1124 | void dealloc(void*); 1125 | void traversalinit(); 1126 | void *traverse(); 1127 | }; 1128 | 1129 | //============================================================================// 1130 | // // 1131 | // badface // 1132 | // // 1133 | // Despite of its name, a 'badface' can be used to represent one of the // 1134 | // following objects: // 1135 | // - a face of a tetrahedron which is (possibly) non-Delaunay; // 1136 | // - an encroached subsegment or subface; // 1137 | // - a bad-quality tetrahedron, i.e, has too large radius-edge ratio; // 1138 | // - a sliver, i.e., has good radius-edge ratio but nearly zero volume; // 1139 | // - a recently flipped face (saved for undoing the flip later). // 1140 | // // 1141 | //============================================================================// 1142 | 1143 | class badface { 1144 | public: 1145 | triface tt; 1146 | face ss; 1147 | REAL key, cent[6]; // circumcenter or cos(dihedral angles) at 6 edges. 1148 | point forg, fdest, fapex, foppo, noppo; 1149 | badface *nextitem; 1150 | badface() : key(0), forg(0), fdest(0), fapex(0), foppo(0), noppo(0), 1151 | nextitem(0) {} 1152 | void init() { 1153 | key = 0.; 1154 | for (int k = 0; k < 6; k++) cent[k] = 0.; 1155 | tt.tet = NULL; tt.ver = 0; 1156 | ss.sh = NULL; ss.shver = 0; 1157 | forg = fdest = fapex = foppo = noppo = NULL; 1158 | nextitem = NULL; 1159 | } 1160 | }; 1161 | 1162 | //============================================================================// 1163 | // // 1164 | // insertvertexflags // 1165 | // // 1166 | // A collection of flags that pass to the routine insertvertex(). // 1167 | // // 1168 | //============================================================================// 1169 | 1170 | class insertvertexflags { 1171 | 1172 | public: 1173 | 1174 | int iloc; // input/output. 1175 | int bowywat, lawson; 1176 | int splitbdflag, validflag, respectbdflag; 1177 | int rejflag, chkencflag, cdtflag; 1178 | int assignmeshsize; 1179 | int sloc, sbowywat; 1180 | 1181 | // Used by Delaunay refinement. 1182 | int collect_inial_cavity_flag; 1183 | int ignore_near_vertex; 1184 | int check_insert_radius; 1185 | int refineflag; // 0, 1, 2, 3 1186 | triface refinetet; 1187 | face refinesh; 1188 | int smlenflag; // for useinsertradius. 1189 | REAL smlen; // for useinsertradius. 1190 | point parentpt; 1191 | 1192 | void init() { 1193 | iloc = bowywat = lawson = 0; 1194 | splitbdflag = validflag = respectbdflag = 0; 1195 | rejflag = chkencflag = cdtflag = 0; 1196 | assignmeshsize = 0; 1197 | sloc = sbowywat = 0; 1198 | 1199 | collect_inial_cavity_flag = 0; 1200 | ignore_near_vertex = 0; 1201 | check_insert_radius = 0; 1202 | refineflag = 0; 1203 | refinetet.tet = NULL; 1204 | refinesh.sh = NULL; 1205 | smlenflag = 0; 1206 | smlen = 0.0; 1207 | parentpt = NULL; 1208 | } 1209 | 1210 | insertvertexflags() { 1211 | init(); 1212 | } 1213 | }; 1214 | 1215 | //============================================================================// 1216 | // // 1217 | // flipconstraints // 1218 | // // 1219 | // A structure of a collection of data (options and parameters) which pass // 1220 | // to the edge flip function flipnm(). // 1221 | // // 1222 | //============================================================================// 1223 | 1224 | class flipconstraints { 1225 | 1226 | public: 1227 | 1228 | // Elementary flip flags. 1229 | int enqflag; // (= flipflag) 1230 | int chkencflag; 1231 | 1232 | // Control flags 1233 | int unflip; // Undo the performed flips. 1234 | int collectnewtets; // Collect the new tets created by flips. 1235 | int collectencsegflag; 1236 | 1237 | // Optimization flags. 1238 | int noflip_in_surface; // do not flip edges (not segment) in surface. 1239 | int remove_ndelaunay_edge; // Remove a non-Delaunay edge. 1240 | REAL bak_tetprism_vol; // The value to be minimized. 1241 | REAL tetprism_vol_sum; 1242 | int remove_large_angle; // Remove a large dihedral angle at edge. 1243 | REAL cosdihed_in; // The input cosine of the dihedral angle (> 0). 1244 | REAL cosdihed_out; // The improved cosine of the dihedral angle. 1245 | REAL max_asp_out; // Max asp ratio after the improvement of dihedral angle. 1246 | 1247 | // Boundary recovery flags. 1248 | int checkflipeligibility; 1249 | point seg[2]; // A constraining edge to be recovered. 1250 | point fac[3]; // A constraining face to be recovered. 1251 | point remvert; // A vertex to be removed. 1252 | 1253 | 1254 | flipconstraints() { 1255 | enqflag = 0; 1256 | chkencflag = 0; 1257 | 1258 | unflip = 0; 1259 | collectnewtets = 0; 1260 | collectencsegflag = 0; 1261 | 1262 | noflip_in_surface = 0; 1263 | remove_ndelaunay_edge = 0; 1264 | bak_tetprism_vol = 0.0; 1265 | tetprism_vol_sum = 0.0; 1266 | remove_large_angle = 0; 1267 | cosdihed_in = 0.0; 1268 | cosdihed_out = 0.0; 1269 | max_asp_out = 0.0; 1270 | 1271 | checkflipeligibility = 0; 1272 | seg[0] = NULL; 1273 | fac[0] = NULL; 1274 | remvert = NULL; 1275 | } 1276 | }; 1277 | 1278 | //============================================================================// 1279 | // // 1280 | // optparameters // 1281 | // // 1282 | // Optimization options and parameters. // 1283 | // // 1284 | //============================================================================// 1285 | 1286 | class optparameters { 1287 | 1288 | public: 1289 | 1290 | // The one of goals of optimization. 1291 | int max_min_volume; // Maximize the minimum volume. 1292 | int min_max_aspectratio; // Minimize the maximum aspect ratio. 1293 | int min_max_dihedangle; // Minimize the maximum dihedral angle. 1294 | 1295 | // The initial and improved value. 1296 | REAL initval, imprval; 1297 | 1298 | int numofsearchdirs; 1299 | REAL searchstep; 1300 | int maxiter; // Maximum smoothing iterations (disabled by -1). 1301 | int smthiter; // Performed iterations. 1302 | 1303 | 1304 | optparameters() { 1305 | max_min_volume = 0; 1306 | min_max_aspectratio = 0; 1307 | min_max_dihedangle = 0; 1308 | 1309 | initval = imprval = 0.0; 1310 | 1311 | numofsearchdirs = 10; 1312 | searchstep = 0.01; 1313 | maxiter = -1; // Unlimited smoothing iterations. 1314 | smthiter = 0; 1315 | 1316 | } 1317 | }; 1318 | 1319 | 1320 | //============================================================================// 1321 | // // 1322 | // Labels (enumeration declarations) used by TetGen. // 1323 | // // 1324 | //============================================================================// 1325 | 1326 | // Labels that signify the type of a vertex. 1327 | enum verttype {UNUSEDVERTEX, DUPLICATEDVERTEX, RIDGEVERTEX, /*ACUTEVERTEX,*/ 1328 | FACETVERTEX, VOLVERTEX, FREESEGVERTEX, FREEFACETVERTEX, 1329 | FREEVOLVERTEX, NREGULARVERTEX, DEADVERTEX}; 1330 | 1331 | // Labels that signify the result of triangle-triangle intersection test. 1332 | enum interresult {DISJOINT, INTERSECT, SHAREVERT, SHAREEDGE, SHAREFACE, 1333 | TOUCHEDGE, TOUCHFACE, ACROSSVERT, ACROSSEDGE, ACROSSFACE, 1334 | SELF_INTERSECT}; 1335 | 1336 | // Labels that signify the result of point location. 1337 | enum locateresult {UNKNOWN, OUTSIDE, INTETRAHEDRON, ONFACE, ONEDGE, ONVERTEX, 1338 | ENCVERTEX, ENCSEGMENT, ENCSUBFACE, NEARVERTEX, NONREGULAR, 1339 | INSTAR, BADELEMENT, NULLCAVITY, SHARPCORNER, FENSEDIN, 1340 | NONCOPLANAR, SELF_ENCROACH}; 1341 | 1342 | //============================================================================// 1343 | // // 1344 | // Variables of TetGen // 1345 | // // 1346 | //============================================================================// 1347 | 1348 | // Pointer to the input data (a set of nodes, a PLC, or a mesh). 1349 | tetgenio *in, *addin; 1350 | 1351 | // Pointer to the switches and parameters. 1352 | tetgenbehavior *b; 1353 | 1354 | // Pointer to a background mesh (contains size specification map). 1355 | tetgenmesh *bgm; 1356 | 1357 | // Memorypools to store mesh elements (points, tetrahedra, subfaces, and 1358 | // segments) and extra pointers between tetrahedra, subfaces, and segments. 1359 | memorypool *tetrahedrons, *subfaces, *subsegs, *points; 1360 | memorypool *tet2subpool, *tet2segpool; 1361 | 1362 | // Memorypools to store bad-quality (or encroached) elements. 1363 | memorypool *badtetrahedrons, *badsubfacs, *badsubsegs; 1364 | memorypool *split_subfaces_pool, *split_segments_pool; 1365 | arraypool *unsplit_badtets, *unsplit_subfaces, *unsplit_segments; 1366 | arraypool *check_tets_list; 1367 | 1368 | badface *stack_enc_segments, *stack_enc_subfaces; 1369 | 1370 | // Bad quality subfaces are ordered by priority queues. 1371 | badface *queuefront[64]; 1372 | badface *queuetail[64]; 1373 | int nextnonemptyq[64]; 1374 | int firstnonemptyq, recentq; 1375 | 1376 | // Bad quality tetrahedra are ordered by priority queues. 1377 | memorypool *badqual_tets_pool; 1378 | badface *bt_queuefront[64]; 1379 | badface *bt_queuetail[64]; 1380 | int bt_nextnonemptyq[64]; 1381 | int bt_firstnonemptyq, bt_recentq; 1382 | 1383 | // A memorypool to store faces to be flipped. 1384 | memorypool *flippool; 1385 | arraypool *later_unflip_queue, *unflipqueue; 1386 | badface *flipstack, *unflip_queue_front, *unflip_queue_tail; 1387 | 1388 | // Arrays used for point insertion (the Bowyer-Watson algorithm). 1389 | arraypool *cavetetlist, *cavebdrylist, *caveoldtetlist; 1390 | arraypool *cave_oldtet_list; // only tetrahedron's 1391 | arraypool *cavetetshlist, *cavetetseglist, *cavetetvertlist; 1392 | arraypool *caveencshlist, *caveencseglist; 1393 | arraypool *caveshlist, *caveshbdlist, *cavesegshlist; 1394 | triface _bw_faces[4096]; // _bw_faces[64][64]; 1395 | 1396 | // Stacks used for CDT construction and boundary recovery. 1397 | arraypool *subsegstack, *subfacstack, *subvertstack; 1398 | arraypool *skipped_segment_list, *skipped_facet_list; 1399 | 1400 | // Arrays of encroached segments and subfaces (for mesh refinement). 1401 | arraypool *encseglist, *encshlist; 1402 | 1403 | // The map between facets to their vertices (for mesh refinement). 1404 | int number_of_facets; 1405 | int *idx2facetlist; 1406 | point *facetverticeslist; 1407 | int *idx_segment_facet_list; // segment-to-facet map. 1408 | int *segment_facet_list; 1409 | int *idx_ridge_vertex_facet_list; // vertex-to-facet map. 1410 | int *ridge_vertex_facet_list; 1411 | 1412 | // The map between segments to their endpoints (for mesh refinement). 1413 | int segmentendpointslist_length; 1414 | point *segmentendpointslist; 1415 | double *segment_info_list; 1416 | int *idx_segment_ridge_vertex_list; // are two ridge vertices form a segment? 1417 | point *segment_ridge_vertex_list; 1418 | 1419 | // The infinite vertex. 1420 | point dummypoint; 1421 | // The recently visited tetrahedron, subface. 1422 | triface recenttet; 1423 | face recentsh; 1424 | 1425 | // PI is the ratio of a circle's circumference to its diameter. 1426 | static REAL PI; 1427 | 1428 | // The list of subdomains. (-A option). 1429 | int subdomains; // Number of subdomains. 1430 | int *subdomain_markers; 1431 | 1432 | // Various variables. 1433 | int numpointattrib; // Number of point attributes. 1434 | int numelemattrib; // Number of tetrahedron attributes. 1435 | int sizeoftensor; // Number of REALs per metric tensor. 1436 | int pointmtrindex; // Index to find the metric tensor of a point. 1437 | int pointparamindex; // Index to find the u,v coordinates of a point. 1438 | int point2simindex; // Index to find a simplex adjacent to a point. 1439 | int pointmarkindex; // Index to find boundary marker of a point. 1440 | int pointinsradiusindex; // Index to find the insertion radius of a point. 1441 | int elemattribindex; // Index to find attributes of a tetrahedron. 1442 | int polarindex; // Index to find the polar plane parameters. 1443 | int volumeboundindex; // Index to find volume bound of a tetrahedron. 1444 | int elemmarkerindex; // Index to find marker of a tetrahedron. 1445 | int shmarkindex; // Index to find boundary marker of a subface. 1446 | int areaboundindex; // Index to find area bound of a subface. 1447 | int checksubsegflag; // Are there segments in the tetrahedralization yet? 1448 | int checksubfaceflag; // Are there subfaces in the tetrahedralization yet? 1449 | int boundary_recovery_flag; 1450 | int checkconstraints; // Are there variant (node, seg, facet) constraints? 1451 | int nonconvex; // Is current mesh non-convex? 1452 | int autofliplinklevel; // The increase of link levels, default is 1. 1453 | int useinsertradius; // Save the insertion radius for Steiner points. 1454 | long samples; // Number of random samples for point location. 1455 | unsigned long randomseed; // Current random number seed. 1456 | REAL cosmaxdihed, cosmindihed; // The cosine values of max/min dihedral. 1457 | REAL cossmtdihed; // The cosine value of a bad dihedral to be smoothed. 1458 | REAL cosslidihed; // The cosine value of the max dihedral of a sliver. 1459 | REAL cos_large_dihed; // The cosine value of large dihedral (135 degree). 1460 | REAL opt_max_sliver_asp_ratio; // = 10 x b->opt_max_asp_ratio. 1461 | REAL minfaceang, minfacetdihed; // The minimum input (dihedral) angles. 1462 | REAL cos_facet_separate_ang_tol; 1463 | REAL cos_collinear_ang_tol; 1464 | REAL tetprism_vol_sum; // The total volume of tetrahedral-prisms (in 4D). 1465 | REAL longest; // The longest possible edge length. 1466 | REAL minedgelength; // = longest * b->epsion. 1467 | REAL xmax, xmin, ymax, ymin, zmax, zmin; // Bounding box of points. 1468 | 1469 | // Options for mesh refinement. 1470 | REAL big_radius_edge_ratio; // calculated by qualitystatistics(). 1471 | REAL smallest_insradius; // Save the smallest insertion radius. 1472 | long elem_limit; 1473 | long insert_point_count; // number of attempted insertions. 1474 | long report_refine_progress; // the next report event. 1475 | long last_point_count; // number of points after last report event. 1476 | long last_insertion_count; // number of insertions after last report event. 1477 | 1478 | // Counters. 1479 | long insegments; // Number of input segments. 1480 | long hullsize; // Number of exterior boundary faces. 1481 | long meshedges; // Number of mesh edges. 1482 | long meshhulledges; // Number of boundary mesh edges. 1483 | long steinerleft; // Number of Steiner points not yet used. 1484 | long dupverts; // Are there duplicated vertices? 1485 | long unuverts; // Are there unused vertices? 1486 | long duplicated_facets_count; // Are there duplicated facets.? 1487 | long nonregularcount; // Are there non-regular vertices? 1488 | long st_segref_count, st_facref_count, st_volref_count; // Steiner points. 1489 | long fillregioncount, cavitycount, cavityexpcount; 1490 | long flip14count, flip26count, flipn2ncount; 1491 | long flip23count, flip32count, flip44count, flip41count; 1492 | long flip31count, flip22count; 1493 | long opt_flips_count, opt_collapse_count, opt_smooth_count; 1494 | long recover_delaunay_count; 1495 | unsigned long totalworkmemory; // Total memory used by working arrays. 1496 | 1497 | 1498 | //============================================================================// 1499 | // // 1500 | // Mesh manipulation primitives // 1501 | // // 1502 | //============================================================================// 1503 | 1504 | // Fast lookup tables for mesh manipulation primitives. 1505 | static int bondtbl[12][12], fsymtbl[12][12]; 1506 | static int esymtbl[12], enexttbl[12], eprevtbl[12]; 1507 | static int enextesymtbl[12], eprevesymtbl[12]; 1508 | static int eorgoppotbl[12], edestoppotbl[12]; 1509 | static int facepivot1[12], facepivot2[12][12]; 1510 | static int orgpivot[12], destpivot[12], apexpivot[12], oppopivot[12]; 1511 | static int tsbondtbl[12][6], stbondtbl[12][6]; 1512 | static int tspivottbl[12][6], stpivottbl[12][6]; 1513 | static int ver2edge[12], edge2ver[6], epivot[12]; 1514 | static int sorgpivot [6], sdestpivot[6], sapexpivot[6]; 1515 | static int snextpivot[6]; 1516 | 1517 | void inittables(); 1518 | 1519 | // Primitives for tetrahedra. 1520 | inline tetrahedron encode(triface& t); 1521 | inline tetrahedron encode2(tetrahedron* ptr, int ver); 1522 | inline void decode(tetrahedron ptr, triface& t); 1523 | inline tetrahedron* decode_tet_only(tetrahedron ptr); 1524 | inline int decode_ver_only(tetrahedron ptr); 1525 | inline void bond(triface& t1, triface& t2); 1526 | inline void dissolve(triface& t); 1527 | inline void esym(triface& t1, triface& t2); 1528 | inline void esymself(triface& t); 1529 | inline void enext(triface& t1, triface& t2); 1530 | inline void enextself(triface& t); 1531 | inline void eprev(triface& t1, triface& t2); 1532 | inline void eprevself(triface& t); 1533 | inline void enextesym(triface& t1, triface& t2); 1534 | inline void enextesymself(triface& t); 1535 | inline void eprevesym(triface& t1, triface& t2); 1536 | inline void eprevesymself(triface& t); 1537 | inline void eorgoppo(triface& t1, triface& t2); 1538 | inline void eorgoppoself(triface& t); 1539 | inline void edestoppo(triface& t1, triface& t2); 1540 | inline void edestoppoself(triface& t); 1541 | inline void fsym(triface& t1, triface& t2); 1542 | inline void fsymself(triface& t); 1543 | inline void fnext(triface& t1, triface& t2); 1544 | inline void fnextself(triface& t); 1545 | inline point org (triface& t); 1546 | inline point dest(triface& t); 1547 | inline point apex(triface& t); 1548 | inline point oppo(triface& t); 1549 | inline void setorg (triface& t, point p); 1550 | inline void setdest(triface& t, point p); 1551 | inline void setapex(triface& t, point p); 1552 | inline void setoppo(triface& t, point p); 1553 | inline REAL elemattribute(tetrahedron* ptr, int attnum); 1554 | inline void setelemattribute(tetrahedron* ptr, int attnum, REAL value); 1555 | inline REAL* get_polar(tetrahedron* ptr); 1556 | inline REAL get_volume(tetrahedron* ptr); 1557 | inline REAL volumebound(tetrahedron* ptr); 1558 | inline void setvolumebound(tetrahedron* ptr, REAL value); 1559 | inline int elemindex(tetrahedron* ptr); 1560 | inline void setelemindex(tetrahedron* ptr, int value); 1561 | inline int elemmarker(tetrahedron* ptr); 1562 | inline void setelemmarker(tetrahedron* ptr, int value); 1563 | inline void infect(triface& t); 1564 | inline void uninfect(triface& t); 1565 | inline bool infected(triface& t); 1566 | inline void marktest(triface& t); 1567 | inline void unmarktest(triface& t); 1568 | inline bool marktested(triface& t); 1569 | inline void markface(triface& t); 1570 | inline void unmarkface(triface& t); 1571 | inline bool facemarked(triface& t); 1572 | inline void markedge(triface& t); 1573 | inline void unmarkedge(triface& t); 1574 | inline bool edgemarked(triface& t); 1575 | inline void marktest2(triface& t); 1576 | inline void unmarktest2(triface& t); 1577 | inline bool marktest2ed(triface& t); 1578 | inline int elemcounter(triface& t); 1579 | inline void setelemcounter(triface& t, int value); 1580 | inline void increaseelemcounter(triface& t); 1581 | inline void decreaseelemcounter(triface& t); 1582 | inline bool ishulltet(triface& t); 1583 | inline bool isdeadtet(triface& t); 1584 | 1585 | // Primitives for subfaces and subsegments. 1586 | inline void sdecode(shellface sptr, face& s); 1587 | inline shellface sencode(face& s); 1588 | inline shellface sencode2(shellface *sh, int shver); 1589 | inline void spivot(face& s1, face& s2); 1590 | inline void spivotself(face& s); 1591 | inline void sbond(face& s1, face& s2); 1592 | inline void sbond1(face& s1, face& s2); 1593 | inline void sdissolve(face& s); 1594 | inline point sorg(face& s); 1595 | inline point sdest(face& s); 1596 | inline point sapex(face& s); 1597 | inline void setsorg(face& s, point pointptr); 1598 | inline void setsdest(face& s, point pointptr); 1599 | inline void setsapex(face& s, point pointptr); 1600 | inline void sesym(face& s1, face& s2); 1601 | inline void sesymself(face& s); 1602 | inline void senext(face& s1, face& s2); 1603 | inline void senextself(face& s); 1604 | inline void senext2(face& s1, face& s2); 1605 | inline void senext2self(face& s); 1606 | inline REAL areabound(face& s); 1607 | inline void setareabound(face& s, REAL value); 1608 | inline int shellmark(face& s); 1609 | inline void setshellmark(face& s, int value); 1610 | inline void sinfect(face& s); 1611 | inline void suninfect(face& s); 1612 | inline bool sinfected(face& s); 1613 | inline void smarktest(face& s); 1614 | inline void sunmarktest(face& s); 1615 | inline bool smarktested(face& s); 1616 | inline void smarktest2(face& s); 1617 | inline void sunmarktest2(face& s); 1618 | inline bool smarktest2ed(face& s); 1619 | inline void smarktest3(face& s); 1620 | inline void sunmarktest3(face& s); 1621 | inline bool smarktest3ed(face& s); 1622 | inline void setfacetindex(face& f, int value); 1623 | inline int getfacetindex(face& f); 1624 | inline bool isdeadsh(face& s); 1625 | 1626 | // Primitives for interacting tetrahedra and subfaces. 1627 | inline void tsbond(triface& t, face& s); 1628 | inline void tsdissolve(triface& t); 1629 | inline void stdissolve(face& s); 1630 | inline void tspivot(triface& t, face& s); 1631 | inline void stpivot(face& s, triface& t); 1632 | 1633 | // Primitives for interacting tetrahedra and segments. 1634 | inline void tssbond1(triface& t, face& seg); 1635 | inline void sstbond1(face& s, triface& t); 1636 | inline void tssdissolve1(triface& t); 1637 | inline void sstdissolve1(face& s); 1638 | inline void tsspivot1(triface& t, face& s); 1639 | inline void sstpivot1(face& s, triface& t); 1640 | 1641 | // Primitives for interacting subfaces and segments. 1642 | inline void ssbond(face& s, face& edge); 1643 | inline void ssbond1(face& s, face& edge); 1644 | inline void ssdissolve(face& s); 1645 | inline void sspivot(face& s, face& edge); 1646 | 1647 | // Primitives for points. 1648 | inline int pointmark(point pt); 1649 | inline void setpointmark(point pt, int value); 1650 | inline enum verttype pointtype(point pt); 1651 | inline void setpointtype(point pt, enum verttype value); 1652 | inline int pointgeomtag(point pt); 1653 | inline void setpointgeomtag(point pt, int value); 1654 | inline REAL pointgeomuv(point pt, int i); 1655 | inline void setpointgeomuv(point pt, int i, REAL value); 1656 | inline void pinfect(point pt); 1657 | inline void puninfect(point pt); 1658 | inline bool pinfected(point pt); 1659 | inline void pmarktest(point pt); 1660 | inline void punmarktest(point pt); 1661 | inline bool pmarktested(point pt); 1662 | inline void pmarktest2(point pt); 1663 | inline void punmarktest2(point pt); 1664 | inline bool pmarktest2ed(point pt); 1665 | inline void pmarktest3(point pt); 1666 | inline void punmarktest3(point pt); 1667 | inline bool pmarktest3ed(point pt); 1668 | inline tetrahedron point2tet(point pt); 1669 | inline void setpoint2tet(point pt, tetrahedron value); 1670 | inline shellface point2sh(point pt); 1671 | inline void setpoint2sh(point pt, shellface value); 1672 | inline point point2ppt(point pt); 1673 | inline void setpoint2ppt(point pt, point value); 1674 | inline tetrahedron point2bgmtet(point pt); 1675 | inline void setpoint2bgmtet(point pt, tetrahedron value); 1676 | inline void setpointinsradius(point pt, REAL value); 1677 | inline REAL getpointinsradius(point pt); 1678 | inline bool issteinerpoint(point pt); 1679 | 1680 | // Advanced primitives. 1681 | inline void point2tetorg(point pt, triface& t); 1682 | inline void point2shorg(point pa, face& s); 1683 | inline point farsorg(face& seg); 1684 | inline point farsdest(face& seg); 1685 | 1686 | //============================================================================// 1687 | // // 1688 | // Memory managment // 1689 | // // 1690 | //============================================================================// 1691 | 1692 | void tetrahedrondealloc(tetrahedron*); 1693 | tetrahedron *tetrahedrontraverse(); 1694 | tetrahedron *alltetrahedrontraverse(); 1695 | void shellfacedealloc(memorypool*, shellface*); 1696 | shellface *shellfacetraverse(memorypool*); 1697 | void pointdealloc(point); 1698 | point pointtraverse(); 1699 | 1700 | void makeindex2pointmap(point*&); 1701 | void makepoint2submap(memorypool*, int*&, face*&); 1702 | void maketetrahedron(triface*); 1703 | void maketetrahedron2(triface*, point, point, point, point); 1704 | void makeshellface(memorypool*, face*); 1705 | void makepoint(point*, enum verttype); 1706 | 1707 | void initializepools(); 1708 | 1709 | //============================================================================// 1710 | // // 1711 | // Advanced geometric predicates and calculations // 1712 | // // 1713 | // the routine insphere_s() implements a simplified symbolic perturbation // 1714 | // scheme from Edelsbrunner, et al [*]. Hence the point-in-sphere test never // 1715 | // returns a zero. The idea is to perturb the weights of vertices in 4D. // 1716 | // // 1717 | // The routine tri_edge_test() determines whether or not a triangle and an // 1718 | // edge intersect in 3D. If they do cross, their intersection type is also // 1719 | // reported. This test is a combination of n 3D orientation tests (3 < n < 9).// 1720 | // It uses the robust orient3d() test to make the branch decisions. // 1721 | // // 1722 | // There are several routines to calculate geometrical quantities, e.g., // 1723 | // circumcenters, angles, dihedral angles, face normals, face areas, etc. // 1724 | // They are implemented using floating-point arithmetics. // 1725 | // // 1726 | //============================================================================// 1727 | 1728 | // Symbolic perturbations (robust) 1729 | REAL insphere_s(REAL*, REAL*, REAL*, REAL*, REAL*); 1730 | REAL orient4d_s(REAL*, REAL*, REAL*, REAL*, REAL*, 1731 | REAL, REAL, REAL, REAL, REAL); 1732 | 1733 | // An embedded 2-dimensional geometric predicate (non-robust) 1734 | REAL incircle3d(point pa, point pb, point pc, point pd); 1735 | 1736 | // Triangle-edge intersection test (robust) 1737 | int tri_edge_2d(point, point, point, point, point, point, int, int*, int*); 1738 | int tri_edge_tail(point,point,point,point,point,point,REAL,REAL,int,int*,int*); 1739 | int tri_edge_test(point, point, point, point, point, point, int, int*, int*); 1740 | 1741 | // Triangle-triangle intersection test (robust) 1742 | int tri_edge_inter_tail(point, point, point, point, point, REAL, REAL); 1743 | int tri_tri_inter(point, point, point, point, point, point); 1744 | 1745 | // Linear algebra functions 1746 | inline REAL dot(REAL* v1, REAL* v2); 1747 | inline void cross(REAL* v1, REAL* v2, REAL* n); 1748 | bool lu_decmp(REAL lu[4][4], int n, int* ps, REAL* d, int N); 1749 | void lu_solve(REAL lu[4][4], int n, int* ps, REAL* b, int N); 1750 | 1751 | // Geometric calculations (non-robust) 1752 | REAL orient3dfast(REAL *pa, REAL *pb, REAL *pc, REAL *pd); 1753 | inline REAL norm2(REAL x, REAL y, REAL z); 1754 | inline REAL distance(REAL* p1, REAL* p2); 1755 | inline REAL distance2(REAL* p1, REAL* p2); 1756 | void facenormal(point pa, point pb, point pc, REAL *n, int pivot, REAL *lav); 1757 | REAL facedihedral(REAL* pa, REAL* pb, REAL* pc1, REAL* pc2); 1758 | REAL triarea(REAL* pa, REAL* pb, REAL* pc); 1759 | REAL interiorangle(REAL* o, REAL* p1, REAL* p2, REAL* n); 1760 | REAL cos_interiorangle(REAL* o, REAL* p1, REAL* p2); 1761 | void projpt2edge(REAL* p, REAL* e1, REAL* e2, REAL* prj); 1762 | void projpt2face(REAL* p, REAL* f1, REAL* f2, REAL* f3, REAL* prj); 1763 | bool circumsphere(REAL*, REAL*, REAL*, REAL*, REAL* cent, REAL* radius); 1764 | bool orthosphere(REAL*,REAL*,REAL*,REAL*,REAL,REAL,REAL,REAL,REAL*,REAL*); 1765 | void planelineint(REAL*, REAL*, REAL*, REAL*, REAL*, REAL*, REAL*); 1766 | int linelineint(REAL*, REAL*, REAL*, REAL*, REAL*, REAL*, REAL*, REAL*); 1767 | REAL tetprismvol(REAL* pa, REAL* pb, REAL* pc, REAL* pd); 1768 | bool calculateabovepoint(arraypool*, point*, point*, point*); 1769 | void calculateabovepoint4(point, point, point, point); 1770 | 1771 | //============================================================================// 1772 | // // 1773 | // Local mesh transformations // 1774 | // // 1775 | // A local transformation replaces a set of tetrahedra with another set that // 1776 | // partitions the same space and boundaries. // 1777 | // // 1778 | // In 3D, the most straightforward local transformations are the elementary // 1779 | // flips performed within the convex hull of five vertices: 2-to-3, 3-to-2, // 1780 | // 1-to-4, and 4-to-1 flips. The numbers indicate the number of tetrahedra // 1781 | // before and after each flip. The 1-to-4 and 4-to-1 flip involve inserting // 1782 | // or deleting a vertex, respectively. // 1783 | // // 1784 | // There are complex local transformations that are a combination of element- // 1785 | // ary flips. For example, a 4-to-4 flip, which replaces two coplanar edges, // 1786 | // combines a 2-to-3 flip and a 3-to-2 flip. Note that the first 2-to-3 flip // 1787 | // will temporarily create a degenerate tetrahedron removed immediately by // 1788 | // the followed 3-to-2 flip. More generally, an n-to-m flip, where n > 3, // 1789 | // m = (n - 2) * 2, which removes an edge, can be done by first performing a // 1790 | // sequence of (n - 3) 2-to-3 flips followed by a 3-to-2 flip. // 1791 | // // 1792 | // The routines flip23(), flip32(), and flip41() perform the three elementray // 1793 | // flips. The flip14() is available inside the routine insertpoint(). // 1794 | // // 1795 | // The routines flipnm() and flipnm_post() implement a generalized edge flip // 1796 | // algorithm that uses elementary flips. // 1797 | // // 1798 | // The routine insertpoint() implements the Bowyer-Watson's cavity algorithm // 1799 | // to insert a vertex. It works for arbitrary tetrahedralization, either // 1800 | // Delaunay, or constrained Delaunay, or non-Delaunay. // 1801 | // // 1802 | //============================================================================// 1803 | 1804 | void flippush(badface*&, triface*); 1805 | 1806 | // The elementary flips. 1807 | void flip23(triface*, int, flipconstraints* fc); 1808 | void flip32(triface*, int, flipconstraints* fc); 1809 | void flip41(triface*, int, flipconstraints* fc); 1810 | 1811 | // A generalized edge flip. 1812 | int flipnm(triface*, int n, int level, int, flipconstraints* fc); 1813 | int flipnm_post(triface*, int n, int nn, int, flipconstraints* fc); 1814 | 1815 | // Point insertion. 1816 | int insertpoint(point, triface*, face*, face*, insertvertexflags*); 1817 | void insertpoint_abort(face*, insertvertexflags*); 1818 | 1819 | //============================================================================// 1820 | // // 1821 | // Delaunay tetrahedralization // 1822 | // // 1823 | // The routine incrementaldelaunay() implemented two incremental algorithms // 1824 | // for constructing Delaunay tetrahedralizations (DTs): the Bowyer-Watson // 1825 | // (B-W) algorithm and the incremental flip algorithm of Edelsbrunner and // 1826 | // Shah, "Incremental topological flipping works for regular triangulation," // 1827 | // Algorithmica, 15:233-241, 1996. // 1828 | // // 1829 | // The routine incrementalflip() implements the flip algorithm of [Edelsbrun- // 1830 | // ner and Shah, 1996]. It flips a queue of locally non-Delaunay faces (in // 1831 | // arbitrary order). The success is guaranteed when the Delaunay tetrahedra- // 1832 | // lization is constructed incrementally by adding one vertex at a time. // 1833 | // // 1834 | // The routine locate() finds a tetrahedron contains a new point in current // 1835 | // DT. It uses a simple stochastic walk algorithm: starting from an arbitrary // 1836 | // tetrahedron in DT, it finds the destination by visit one tetrahedron at a // 1837 | // time, randomly chooses a tetrahedron if there are more than one choices. // 1838 | // This algorithm terminates due to Edelsbrunner's acyclic theorem. // 1839 | // // 1840 | // Choose a good starting tetrahedron is crucial to the speed of the walk. // 1841 | // TetGen initially uses the "jump-and-walk" algorithm of Muecke, E.P., Saias,// 1842 | // I., and Zhu, B. "Fast Randomized Point Location Without Preprocessing." In // 1843 | // Proceedings of the 12th ACM Symposium on Computational Geometry, 274-283, // 1844 | // 1996. It first randomly samples several tetrahedra in the DT and then // 1845 | // choosing the closet one to start walking. // 1846 | // // 1847 | // The above algorithm slows download dramatically as the number of points // 1848 | // grows -- reported in Amenta, N., Choi, S. and Rote, G., "Incremental // 1849 | // construction con {BRIO}," In Proceedings of 19th ACM Symposium on Computa- // 1850 | // tional Geometry, 211-219, 2003. On the other hand, Liu and Snoeyink showed // 1851 | // that the point location could be made in constant time if the points are // 1852 | // pre-sorted so that the nearby points in space have nearby indices, then // 1853 | // adding the points in this order. They sorted the points along the 3D // 1854 | // Hilbert curve. // 1855 | // // 1856 | // The routine hilbert_sort3() sorts a set of 3D points along the 3D Hilbert // 1857 | // curve. It recursively splits a point set according to the Hilbert indices // 1858 | // mapped to the subboxes of the bounding box of the point set. The Hilbert // 1859 | // indices is calculated by Butz's algorithm in 1971. An excellent exposition // 1860 | // of this algorithm can be found in the paper of Hamilton, C., "Compact // 1861 | // Hilbert Indices", Technical Report CS-2006-07, Computer Science, Dalhousie // 1862 | // University, 2006 (the Section 2). My implementation also referenced Steven // 1863 | // Witham's performance of "Hilbert walk" (hopefully, it is still available // 1864 | // at http://www.tiac.net/~sw/2008/10/Hilbert/). // 1865 | // // 1866 | // TetGen sorts the points using the method in the paper of Boissonnat,J.-D., // 1867 | // Devillers, O. and Hornus, S. "Incremental Construction of the Delaunay // 1868 | // Triangulation and the Delaunay Graph in Medium Dimension," In Proceedings // 1869 | // of the 25th ACM Symposium on Computational Geometry, 2009. It first // 1870 | // randomly sorts the points into subgroups using the Biased Randomized // 1871 | // Insertion Ordering (BRIO) of Amenta et al 2003, then sorts the points in // 1872 | // each subgroup along the 3D Hilbert curve. Inserting points in this order // 1873 | // ensure a randomized "sprinkling" of the points over the domain, while // 1874 | // sorting of each subset provides locality. // 1875 | // // 1876 | //============================================================================// 1877 | 1878 | void transfernodes(); 1879 | 1880 | // Point sorting. 1881 | int transgc[8][3][8], tsb1mod3[8]; 1882 | void hilbert_init(int n); 1883 | int hilbert_split(point* vertexarray, int arraysize, int gc0, int gc1, 1884 | REAL, REAL, REAL, REAL, REAL, REAL); 1885 | void hilbert_sort3(point* vertexarray, int arraysize, int e, int d, 1886 | REAL, REAL, REAL, REAL, REAL, REAL, int depth); 1887 | void brio_multiscale_sort(point*,int,int threshold,REAL ratio,int* depth); 1888 | 1889 | // Point location. 1890 | unsigned long randomnation(unsigned int choices); 1891 | void randomsample(point searchpt, triface *searchtet); 1892 | enum locateresult locate(point searchpt, triface *searchtet, int chkencflag = 0); 1893 | 1894 | // Incremental Delaunay construction. 1895 | enum locateresult locate_dt(point searchpt, triface *searchtet); 1896 | int insert_vertex_bw(point, triface*, insertvertexflags*); 1897 | void initialdelaunay(point pa, point pb, point pc, point pd); 1898 | void incrementaldelaunay(clock_t&); 1899 | 1900 | //============================================================================// 1901 | // // 1902 | // Surface triangulation // 1903 | // // 1904 | //============================================================================// 1905 | 1906 | void flipshpush(face*); 1907 | void flip22(face*, int, int); 1908 | void flip31(face*, int); 1909 | long lawsonflip(); 1910 | int sinsertvertex(point newpt, face*, face*, int iloc, int bowywat, int); 1911 | int sremovevertex(point delpt, face*, face*, int lawson); 1912 | 1913 | enum locateresult slocate(point, face*, int, int, int); 1914 | enum interresult sscoutsegment(face*, point, int, int, int); 1915 | void scarveholes(int, REAL*); 1916 | int triangulate(int, arraypool*, arraypool*, int, REAL*); 1917 | 1918 | void unifysegments(); 1919 | void identifyinputedges(point*); 1920 | void mergefacets(); 1921 | void meshsurface(); 1922 | 1923 | 1924 | //============================================================================// 1925 | // // 1926 | // Constrained Delaunay tetrahedralization // 1927 | // // 1928 | // A constrained Delaunay tetrahedralization (CDT) is a variation of a Delau- // 1929 | // nay tetrahedralization (DT) that respects the boundary of a 3D PLC (mesh // 1930 | // domain). A crucial difference between a CDT and a DT is that triangles in // 1931 | // the PLC's polygons are not required to be locally Delaunay, which frees // 1932 | // the CDT to respect the PLC's polygons better. CDTs have optimal properties // 1933 | // similar to those of DTs. // 1934 | // // 1935 | // Steiner Points and Steiner CDTs. It is well-known that even a simple 3D // 1936 | // polyhedron may not have a tetrahedralization which only uses its vertices. // 1937 | // Some extra points, so-called "Steiner points" are needed to form a tetrah- // 1938 | // edralization of such polyhedron. A Steiner CDT of a 3D PLC is a CDT // 1939 | // containing Steiner points. TetGen generates Steiner CDTs. // 1940 | // // 1941 | // The routine constraineddelaunay() creates a (Steiner) CDT of the PLC // 1942 | // (including Steiner points). It has two steps, (1) segment recovery and (2) // 1943 | // facet (polygon) recovery. // 1944 | // // 1945 | // The routine delaunizesegments() implements the segment recovery algorithm // 1946 | // of Si, H., and Gaertner, K. "Meshing Piecewise Linear Complexes by // 1947 | // Constrained Delaunay Tetrahedralizations," In Proceedings of the 14th // 1948 | // International Meshing Roundtable, 147--163, 2005. It adds Steiner points // 1949 | // into non-Delaunay segments until all subsegments appear together in a DT. // 1950 | // The running time of this algorithm is proportional to the number of // 1951 | // Steiner points. // 1952 | // // 1953 | // There are two incremental facet recovery algorithms: the cavity re- // 1954 | // triangulation algorithm of Si, H., and Gaertner, K. "3D Boundary Recovery // 1955 | // by Constrained Delaunay Tetrahedralization," International Journal for // 1956 | // Numerical Methods in Engineering, 85:1341-1364, 2011, and the flip // 1957 | // algorithm of Shewchuk, J. "Updating and Constructing Constrained Delaunay // 1958 | // and Constrained Regular Triangulations by Flips." In Proceedings of the // 1959 | // 19th ACM Symposium on Computational Geometry, 86-95, 2003. // 1960 | // // 1961 | // Although no Steiner point is needed in step (2), a facet with non-coplanar // 1962 | // vertices might need Steiner points. It is discussed in the paper of Si, H.,// 1963 | // and Shewchuk, J., "Incrementally Constructing and Updating Constrained // 1964 | // Delaunay Tetrahedralizations with Finite Precision Coordinates." In // 1965 | // Proceedings of the 21th International Meshing Roundtable, 2012. // 1966 | // // 1967 | // Our implementation of the facet recovery algorithms recovers a "missing // 1968 | // region" at a time. Each missing region is a subset of connected interiors // 1969 | // of a polygon. The routine formcavity() creates the cavity of crossing // 1970 | // tetrahedra of the missing region. The cavity re-triangulation algorithm is // 1971 | // implemented by three subroutines, delaunizecavity(), fillcavity(), and // 1972 | // carvecavity(). Since it may fail due to non-coplanar vertices, the // 1973 | // subroutine restorecavity() is used to restore the original cavity. // 1974 | // // 1975 | // The routine flipinsertfacet() implements the flip algorithm. The sub- // 1976 | // routine flipcertify() is used to maintain the priority queue of flips. // 1977 | // The routine refineregion() is called when the facet recovery algorithm // 1978 | // fails to recover a missing region. It inserts Steiner points to refine the // 1979 | // missing region. To avoid inserting Steiner points very close to existing // 1980 | // segments. The classical encroachment rules of the Delaunay refinement // 1981 | // algorithm are used to choose the Steiner points. The routine // 1982 | // constrainedfacets() does the facet recovery by using either the cavity re- // 1983 | // triangulation algorithm (default) or the flip algorithm. It results in a // 1984 | // CDT of the (modified) PLC (including Steiner points). // 1985 | // // 1986 | //============================================================================// 1987 | 1988 | enum interresult finddirection(triface* searchtet, point endpt); 1989 | enum interresult scoutsegment(point, point, face*, triface*, point*, 1990 | arraypool*); 1991 | int getsteinerptonsegment(face* seg, point refpt, point steinpt); 1992 | void delaunizesegments(); 1993 | 1994 | int scoutsubface(face* searchsh,triface* searchtet,int shflag); 1995 | void formregion(face*, arraypool*, arraypool*, arraypool*); 1996 | int scoutcrossedge(triface& crosstet, arraypool*, arraypool*); 1997 | bool formcavity(triface*, arraypool*, arraypool*, arraypool*, arraypool*, 1998 | arraypool*, arraypool*); 1999 | // Facet recovery by cavity re-triangulation [Si and Gaertner 2011]. 2000 | void delaunizecavity(arraypool*, arraypool*, arraypool*, arraypool*, 2001 | arraypool*, arraypool*); 2002 | bool fillcavity(arraypool*, arraypool*, arraypool*, arraypool*, 2003 | arraypool*, arraypool*, triface* crossedge); 2004 | void carvecavity(arraypool*, arraypool*, arraypool*); 2005 | void restorecavity(arraypool*, arraypool*, arraypool*, arraypool*); 2006 | // Facet recovery by flips [Shewchuk 2003]. 2007 | void flipcertify(triface *chkface, badface **pqueue, point, point, point); 2008 | void flipinsertfacet(arraypool*, arraypool*, arraypool*, arraypool*); 2009 | 2010 | int insertpoint_cdt(point, triface*, face*, face*, insertvertexflags*, 2011 | arraypool*, arraypool*, arraypool*, arraypool*, 2012 | arraypool*, arraypool*); 2013 | void refineregion(face&, arraypool*, arraypool*, arraypool*, arraypool*, 2014 | arraypool*, arraypool*); 2015 | void constrainedfacets(); 2016 | 2017 | void constraineddelaunay(clock_t&); 2018 | 2019 | //============================================================================// 2020 | // // 2021 | // Constrained tetrahedralizations. // 2022 | // // 2023 | //============================================================================// 2024 | 2025 | void sort_2pts(point p1, point p2, point ppt[2]); 2026 | void sort_3pts(point p1, point p2, point p3, point ppt[3]); 2027 | 2028 | bool is_collinear_at(point mid, point left, point right); 2029 | bool is_segment(point p1, point p2); 2030 | bool valid_constrained_f23(triface&, point pd, point pe); 2031 | bool valid_constrained_f32(triface*, point pa, point pb); 2032 | 2033 | int checkflipeligibility(int fliptype, point, point, point, point, point, 2034 | int level, int edgepivot, flipconstraints* fc); 2035 | 2036 | int removeedgebyflips(triface*, flipconstraints*); 2037 | int removefacebyflips(triface*, flipconstraints*); 2038 | 2039 | int recoveredgebyflips(point, point, face*, triface*, int fullsearch, int& idir); 2040 | int add_steinerpt_in_schoenhardtpoly(triface*, int, int, int chkencflag); 2041 | int add_steinerpt_in_segment(face*, int searchlevel, int& idir); 2042 | int add_steinerpt_to_recover_edge(point, point, face*, int, int, int& idir); 2043 | int recoversegments(arraypool*, int fullsearch, int steinerflag); 2044 | 2045 | int recoverfacebyflips(point,point,point,face*,triface*,int&,point*,point*); 2046 | int recoversubfaces(arraypool*, int steinerflag); 2047 | 2048 | int getvertexstar(int, point searchpt, arraypool*, arraypool*, arraypool*); 2049 | int getedge(point, point, triface*); 2050 | int reduceedgesatvertex(point startpt, arraypool* endptlist); 2051 | int removevertexbyflips(point steinerpt); 2052 | 2053 | int smoothpoint(point smtpt, arraypool*, int ccw, optparameters *opm); 2054 | int suppressbdrysteinerpoint(point steinerpt); 2055 | int suppresssteinerpoints(); 2056 | 2057 | void recoverboundary(clock_t&); 2058 | 2059 | //============================================================================// 2060 | // // 2061 | // Mesh reconstruction // 2062 | // // 2063 | //============================================================================// 2064 | 2065 | void carveholes(); 2066 | 2067 | void reconstructmesh(); 2068 | 2069 | int search_face(point p0, point p1, point p2, triface &tetloop); 2070 | int search_edge(point p0, point p1, triface &tetloop); 2071 | int scout_point(point, triface*, int randflag); 2072 | REAL getpointmeshsize(point, triface*, int iloc); 2073 | void interpolatemeshsize(); 2074 | 2075 | void insertconstrainedpoints(point *insertarray, int arylen, int rejflag); 2076 | void insertconstrainedpoints(tetgenio *addio); 2077 | 2078 | void collectremovepoints(arraypool *remptlist); 2079 | void meshcoarsening(); 2080 | 2081 | //============================================================================// 2082 | // // 2083 | // Mesh refinement // 2084 | // // 2085 | // The purpose of mesh refinement is to obtain a tetrahedral mesh with well- // 2086 | // -shaped tetrahedra and appropriate mesh size. It is necessary to insert // 2087 | // new Steiner points to achieve this property. The questions are (1) how to // 2088 | // choose the Steiner points? and (2) how to insert them? // 2089 | // // 2090 | // Delaunay refinement is a technique first developed by Chew [1989] and // 2091 | // Ruppert [1993, 1995] to generate quality triangular meshes in the plane. // 2092 | // It provides guarantee on the smallest angle of the triangles. Rupper's // 2093 | // algorithm guarantees that the mesh is size-optimal (to within a constant // 2094 | // factor) among all meshes with the same quality. // 2095 | // Shewchuk generalized Ruppert's algorithm into 3D in his PhD thesis // 2096 | // [Shewchuk 1997]. A short version of his algorithm appears in "Tetrahedral // 2097 | // Mesh Generation by Delaunay Refinement," In Proceedings of the 14th ACM // 2098 | // Symposium on Computational Geometry, 86-95, 1998. It guarantees that all // 2099 | // tetrahedra of the output mesh have a "radius-edge ratio" (equivalent to // 2100 | // the minimal face angle) bounded. However, it does not remove slivers, a // 2101 | // type of very flat tetrahedra which can have no small face angles but have // 2102 | // very small (and large) dihedral angles. Moreover, it may not terminate if // 2103 | // the input PLC contains "sharp features", e.g., two edges (or two facets) // 2104 | // meet at an acute angle (or dihedral angle). // 2105 | // // 2106 | // TetGen uses the basic Delaunay refinement scheme to insert Steiner points. // 2107 | // While it always maintains a constrained Delaunay mesh. The algorithm is // 2108 | // described in Si, H., "Adaptive Constrained Delaunay Mesh Generation," // 2109 | // International Journal for Numerical Methods in Engineering, 75:856-880. // 2110 | // This algorithm always terminates and sharp features are easily preserved. // 2111 | // The mesh has good quality (same as Shewchuk's Delaunay refinement algori- // 2112 | // thm) in the bulk of the mesh domain. Moreover, it supports the generation // 2113 | // of adaptive mesh according to a (isotropic) mesh sizing function. // 2114 | // // 2115 | //============================================================================// 2116 | 2117 | void makesegmentendpointsmap(); 2118 | REAL set_ridge_vertex_protecting_ball(point); 2119 | REAL get_min_angle_at_ridge_vertex(face* seg); 2120 | REAL get_min_diahedral_angle(face* seg); 2121 | void create_segment_info_list(); 2122 | 2123 | void makefacetverticesmap(); 2124 | void create_segment_facet_map(); 2125 | 2126 | int ridge_vertices_adjacent(point, point); 2127 | int facet_ridge_vertex_adjacent(face *, point); 2128 | int segsegadjacent(face *, face *); 2129 | int segfacetadjacent(face *checkseg, face *checksh); 2130 | int facetfacetadjacent(face *, face *); 2131 | bool is_sharp_segment(face* seg); 2132 | bool does_seg_contain_acute_vertex(face* seg); 2133 | bool create_a_shorter_edge(point steinerpt, point nearpt); 2134 | 2135 | void enqueuesubface(memorypool*, face*); 2136 | void enqueuetetrahedron(triface*); 2137 | 2138 | bool check_encroachment(point pa, point pb, point checkpt); 2139 | bool check_enc_segment(face *chkseg, point *pencpt); 2140 | bool get_steiner_on_segment(face* seg, point encpt, point newpt); 2141 | bool split_segment(face *splitseg, point encpt, REAL *param, int qflag, int, int*); 2142 | void repairencsegs(REAL *param, int qflag, int chkencflag); 2143 | 2144 | bool get_subface_ccent(face *chkfac, REAL *ccent); 2145 | bool check_enc_subface(face *chkfac, point *pencpt, REAL *ccent, REAL *radius); 2146 | bool check_subface(face *chkfac, REAL *ccent, REAL radius, REAL *param); 2147 | void enqueue_subface(face *bface, point encpt, REAL *ccent, REAL *param); 2148 | badface* top_subface(); 2149 | void dequeue_subface(); 2150 | void parallel_shift(point pa, point pb, point pc, point pt, REAL* ppt); 2151 | enum locateresult locate_on_surface(point searchpt, face* searchsh); 2152 | bool split_subface(face *splitfac, point encpt, REAL *ccent, REAL*, int, int, int*); 2153 | void repairencfacs(REAL *param, int qflag, int chkencflag); 2154 | 2155 | bool check_tetrahedron(triface *chktet, REAL* param, int& qflag); 2156 | bool checktet4split(triface *chktet, REAL* param, int& qflag); 2157 | enum locateresult locate_point_walk(point searchpt, triface*, int chkencflag); 2158 | bool split_tetrahedron(triface*, REAL*, int, int, insertvertexflags &ivf); 2159 | void repairbadtets(REAL queratio, int chkencflag); 2160 | 2161 | void delaunayrefinement(); 2162 | 2163 | //============================================================================// 2164 | // // 2165 | // Mesh optimization // 2166 | // // 2167 | //============================================================================// 2168 | 2169 | long lawsonflip3d(flipconstraints *fc); 2170 | void recoverdelaunay(); 2171 | 2172 | int get_seg_laplacian_center(point mesh_vert, REAL target[3]); 2173 | int get_surf_laplacian_center(point mesh_vert, REAL target[3]); 2174 | int get_laplacian_center(point mesh_vert, REAL target[3]); 2175 | bool move_vertex(point mesh_vert, REAL target[3]); 2176 | void smooth_vertices(); 2177 | 2178 | bool get_tet(point, point, point, point, triface *); 2179 | bool get_tetqual(triface *chktet, point oppo_pt, badface *bf); 2180 | bool get_tetqual(point, point, point, point, badface *bf); 2181 | void enqueue_badtet(badface *bf); 2182 | badface* top_badtet(); 2183 | void dequeue_badtet(); 2184 | 2185 | bool add_steinerpt_to_repair(badface *bf, bool bSmooth); 2186 | bool flip_edge_to_improve(triface *sliver_edge, REAL& improved_cosmaxd); 2187 | bool repair_tet(badface *bf, bool bFlips, bool bSmooth, bool bSteiners); 2188 | long repair_badqual_tets(bool bFlips, bool bSmooth, bool bSteiners); 2189 | void improve_mesh(); 2190 | 2191 | //============================================================================// 2192 | // // 2193 | // Mesh check and statistics // 2194 | // // 2195 | //============================================================================// 2196 | 2197 | // Mesh validations. 2198 | int check_mesh(int topoflag); 2199 | int check_shells(); 2200 | int check_segments(); 2201 | int check_delaunay(int perturb = 1); 2202 | int check_regular(int); 2203 | int check_conforming(int); 2204 | 2205 | // Mesh statistics. 2206 | void printfcomma(unsigned long n); 2207 | void qualitystatistics(); 2208 | void memorystatistics(); 2209 | void statistics(); 2210 | 2211 | //============================================================================// 2212 | // // 2213 | // Mesh output // 2214 | // // 2215 | //============================================================================// 2216 | 2217 | void jettisonnodes(); 2218 | void highorder(); 2219 | void indexelements(); 2220 | void numberedges(); 2221 | void outnodes(tetgenio*); 2222 | void outmetrics(tetgenio*); 2223 | void outelements(tetgenio*); 2224 | void outfaces(tetgenio*); 2225 | void outhullfaces(tetgenio*); 2226 | void outsubfaces(tetgenio*); 2227 | void outedges(tetgenio*); 2228 | void outsubsegments(tetgenio*); 2229 | void outneighbors(tetgenio*); 2230 | void outvoronoi(tetgenio*); 2231 | void outsmesh(char*); 2232 | void outmesh2medit(char*); 2233 | void outmesh2vtk(char*, int); 2234 | void out_surfmesh_vtk(char*, int); 2235 | void out_intersected_facets(); 2236 | 2237 | 2238 | 2239 | 2240 | //============================================================================// 2241 | // // 2242 | // Constructor & destructor // 2243 | // // 2244 | //============================================================================// 2245 | 2246 | void initializetetgenmesh() 2247 | { 2248 | in = addin = NULL; 2249 | b = NULL; 2250 | bgm = NULL; 2251 | 2252 | tetrahedrons = subfaces = subsegs = points = NULL; 2253 | tet2segpool = tet2subpool = NULL; 2254 | dummypoint = NULL; 2255 | 2256 | badtetrahedrons = badsubfacs = badsubsegs = NULL; 2257 | split_segments_pool = split_subfaces_pool = NULL; 2258 | unsplit_badtets = unsplit_subfaces = unsplit_segments = NULL; 2259 | check_tets_list = NULL; 2260 | badqual_tets_pool = NULL; 2261 | 2262 | stack_enc_segments = stack_enc_subfaces = NULL; 2263 | 2264 | flippool = NULL; 2265 | flipstack = unflip_queue_front = unflip_queue_tail = NULL; 2266 | later_unflip_queue = unflipqueue = NULL; 2267 | 2268 | cavetetlist = cavebdrylist = caveoldtetlist = NULL; 2269 | cave_oldtet_list = NULL; 2270 | cavetetshlist = cavetetseglist = cavetetvertlist = NULL; 2271 | caveencshlist = caveencseglist = NULL; 2272 | caveshlist = caveshbdlist = cavesegshlist = NULL; 2273 | 2274 | subsegstack = subfacstack = subvertstack = NULL; 2275 | skipped_segment_list = skipped_facet_list = NULL; 2276 | 2277 | encseglist = encshlist = NULL; 2278 | 2279 | number_of_facets = 0; 2280 | idx2facetlist = NULL; 2281 | facetverticeslist = NULL; 2282 | idx_segment_facet_list = NULL; 2283 | segment_facet_list = NULL; 2284 | idx_ridge_vertex_facet_list = NULL; 2285 | ridge_vertex_facet_list = NULL; 2286 | 2287 | segmentendpointslist_length = 0; 2288 | segmentendpointslist = NULL; 2289 | segment_info_list = NULL; 2290 | idx_segment_ridge_vertex_list = NULL; 2291 | segment_ridge_vertex_list = NULL; 2292 | 2293 | subdomains = 0; 2294 | subdomain_markers = NULL; 2295 | 2296 | numpointattrib = numelemattrib = 0; 2297 | sizeoftensor = 0; 2298 | pointmtrindex = 0; 2299 | pointparamindex = 0; 2300 | pointmarkindex = 0; 2301 | point2simindex = 0; 2302 | pointinsradiusindex = 0; 2303 | elemattribindex = 0; 2304 | polarindex = 0; 2305 | volumeboundindex = 0; 2306 | shmarkindex = 0; 2307 | areaboundindex = 0; 2308 | checksubsegflag = 0; 2309 | checksubfaceflag = 0; 2310 | boundary_recovery_flag = 0; 2311 | checkconstraints = 0; 2312 | nonconvex = 0; 2313 | autofliplinklevel = 1; 2314 | useinsertradius = 0; 2315 | samples = 0l; 2316 | randomseed = 1l; 2317 | minfaceang = minfacetdihed = PI; 2318 | cos_facet_separate_ang_tol = cos(179.9/180.*PI); 2319 | cos_collinear_ang_tol = cos(179.9/180.*PI); 2320 | tetprism_vol_sum = 0.0; 2321 | longest = minedgelength = 0.0; 2322 | xmax = xmin = ymax = ymin = zmax = zmin = 0.0; 2323 | 2324 | smallest_insradius = 1.e+30; 2325 | big_radius_edge_ratio = 100.0; 2326 | elem_limit = 0; 2327 | insert_point_count = 0l; 2328 | report_refine_progress = 0l; 2329 | last_point_count = 0l; 2330 | last_insertion_count = 0l; 2331 | 2332 | insegments = 0l; 2333 | hullsize = 0l; 2334 | meshedges = meshhulledges = 0l; 2335 | steinerleft = -1; 2336 | dupverts = 0l; 2337 | unuverts = 0l; 2338 | duplicated_facets_count = 0l; 2339 | nonregularcount = 0l; 2340 | st_segref_count = st_facref_count = st_volref_count = 0l; 2341 | fillregioncount = cavitycount = cavityexpcount = 0l; 2342 | flip14count = flip26count = flipn2ncount = 0l; 2343 | flip23count = flip32count = flip44count = flip41count = 0l; 2344 | flip22count = flip31count = 0l; 2345 | recover_delaunay_count = 0l; 2346 | opt_flips_count = opt_collapse_count = opt_smooth_count = 0l; 2347 | totalworkmemory = 0l; 2348 | 2349 | } // tetgenmesh() 2350 | 2351 | void freememory() 2352 | { 2353 | if (bgm != NULL) { 2354 | delete bgm; 2355 | } 2356 | 2357 | if (points != (memorypool *) NULL) { 2358 | delete points; 2359 | delete [] dummypoint; 2360 | } 2361 | if (tetrahedrons != (memorypool *) NULL) { 2362 | delete tetrahedrons; 2363 | } 2364 | if (subfaces != (memorypool *) NULL) { 2365 | delete subfaces; 2366 | delete subsegs; 2367 | } 2368 | if (tet2segpool != NULL) { 2369 | delete tet2segpool; 2370 | delete tet2subpool; 2371 | } 2372 | 2373 | if (badtetrahedrons) { 2374 | delete badtetrahedrons; 2375 | } 2376 | if (badsubfacs) { 2377 | delete badsubfacs; 2378 | } 2379 | if (badsubsegs) { 2380 | delete badsubsegs; 2381 | } 2382 | if (unsplit_badtets) { 2383 | delete unsplit_badtets; 2384 | } 2385 | if (check_tets_list) { 2386 | delete check_tets_list; 2387 | } 2388 | 2389 | if (flippool != NULL) { 2390 | delete flippool; 2391 | delete later_unflip_queue; 2392 | delete unflipqueue; 2393 | } 2394 | 2395 | if (cavetetlist != NULL) { 2396 | delete cavetetlist; 2397 | delete cavebdrylist; 2398 | delete caveoldtetlist; 2399 | delete cavetetvertlist; 2400 | delete cave_oldtet_list; 2401 | } 2402 | 2403 | if (caveshlist != NULL) { 2404 | delete caveshlist; 2405 | delete caveshbdlist; 2406 | delete cavesegshlist; 2407 | delete cavetetshlist; 2408 | delete cavetetseglist; 2409 | delete caveencshlist; 2410 | delete caveencseglist; 2411 | } 2412 | 2413 | if (subsegstack != NULL) { 2414 | delete subsegstack; 2415 | delete subfacstack; 2416 | delete subvertstack; 2417 | } 2418 | 2419 | if (idx2facetlist != NULL) { 2420 | delete [] idx2facetlist; 2421 | delete [] facetverticeslist; 2422 | delete [] idx_segment_facet_list; 2423 | delete [] segment_facet_list; 2424 | delete [] idx_ridge_vertex_facet_list; 2425 | delete [] ridge_vertex_facet_list; 2426 | } 2427 | 2428 | if (segmentendpointslist != NULL) { 2429 | delete [] segmentendpointslist; 2430 | delete [] idx_segment_ridge_vertex_list; 2431 | delete [] segment_ridge_vertex_list; 2432 | } 2433 | 2434 | if (segment_info_list != NULL) { 2435 | delete [] segment_info_list; 2436 | } 2437 | 2438 | if (subdomain_markers != NULL) { 2439 | delete [] subdomain_markers; 2440 | } 2441 | 2442 | initializetetgenmesh(); 2443 | } 2444 | 2445 | tetgenmesh() 2446 | { 2447 | initializetetgenmesh(); 2448 | } 2449 | 2450 | ~tetgenmesh() 2451 | { 2452 | freememory(); 2453 | } // ~tetgenmesh() 2454 | 2455 | }; // End of class tetgenmesh. 2456 | 2457 | //============================================================================// 2458 | // // 2459 | // tetrahedralize() Interface for using TetGen's library to generate // 2460 | // Delaunay tetrahedralizations, constrained Delaunay // 2461 | // tetrahedralizations, quality tetrahedral meshes. // 2462 | // // 2463 | // 'in' is an object of 'tetgenio' containing a PLC or a previously generated // 2464 | // tetrahedral mesh you want to refine. 'out' is another object of 'tetgenio'// 2465 | // for returing the generated tetrahedral mesh. If it is a NULL pointer, the // 2466 | // output mesh is saved to file(s). If 'bgmin' != NULL, it contains a back- // 2467 | // ground mesh defining a mesh size function. // 2468 | // // 2469 | //============================================================================// 2470 | 2471 | void tetrahedralize(tetgenbehavior *b, tetgenio *in, tetgenio *out, 2472 | tetgenio *addin = NULL, tetgenio *bgmin = NULL); 2473 | 2474 | #ifdef TETLIBRARY 2475 | void tetrahedralize(char *switches, tetgenio *in, tetgenio *out, 2476 | tetgenio *addin = NULL, tetgenio *bgmin = NULL); 2477 | 2478 | #endif // #ifdef TETLIBRARY 2479 | 2480 | //============================================================================// 2481 | // // 2482 | // terminatetetgen() Terminate TetGen with a given exit code. // 2483 | // // 2484 | //============================================================================// 2485 | 2486 | 2487 | inline void terminatetetgen(tetgenmesh *m, int x) 2488 | { 2489 | #ifdef TETLIBRARY 2490 | throw x; 2491 | #else 2492 | switch (x) { 2493 | case 1: // Out of memory. 2494 | printf("Error: Out of memory.\n"); 2495 | break; 2496 | case 2: // Encounter an internal error. 2497 | printf("Please report this bug to Hang.Si@wias-berlin.de. Include\n"); 2498 | printf(" the message above, your input data set, and the exact\n"); 2499 | printf(" command line you used to run this program, thank you.\n"); 2500 | break; 2501 | case 3: 2502 | printf("The input surface mesh contain self-intersections. Program stopped.\n"); 2503 | //printf("Hint: use -d option to detect all self-intersections.\n"); 2504 | break; 2505 | case 4: 2506 | printf("A very small input feature size was detected. Program stopped.\n"); 2507 | if (m) { 2508 | printf("Hint: use -T option to set a smaller tolerance. Current is %g\n", 2509 | m->b->epsilon); 2510 | } 2511 | break; 2512 | case 5: 2513 | printf("Two very close input facets were detected. Program stopped.\n"); 2514 | printf("Hint: use -Y option to avoid adding Steiner points in boundary.\n"); 2515 | break; 2516 | case 10: 2517 | printf("An input error was detected. Program stopped.\n"); 2518 | break; 2519 | case 200: 2520 | printf("Boundary contains Steiner points (-YY option). Program stopped.\n"); 2521 | break; 2522 | } // switch (x) 2523 | exit(x); 2524 | #endif // #ifdef TETLIBRARY 2525 | } 2526 | 2527 | //============================================================================// 2528 | // // 2529 | // Primitives for tetrahedra // 2530 | // // 2531 | //============================================================================// 2532 | 2533 | // encode() compress a handle into a single pointer. It relies on the 2534 | // assumption that all addresses of tetrahedra are aligned to sixteen- 2535 | // byte boundaries, so that the last four significant bits are zero. 2536 | 2537 | inline tetgenmesh::tetrahedron tetgenmesh::encode(triface& t) { 2538 | return (tetrahedron) ((uintptr_t) (t).tet | (uintptr_t) (t).ver); 2539 | } 2540 | 2541 | inline tetgenmesh::tetrahedron tetgenmesh::encode2(tetrahedron* ptr, int ver) { 2542 | return (tetrahedron) ((uintptr_t) (ptr) | (uintptr_t) (ver)); 2543 | } 2544 | 2545 | // decode() converts a pointer to a handle. The version is extracted from 2546 | // the four least significant bits of the pointer. 2547 | 2548 | inline void tetgenmesh::decode(tetrahedron ptr, triface& t) { 2549 | (t).ver = (int) ((uintptr_t) (ptr) & (uintptr_t) 15); 2550 | (t).tet = (tetrahedron *) ((uintptr_t) (ptr) ^ (uintptr_t) (t).ver); 2551 | } 2552 | 2553 | inline tetgenmesh::tetrahedron* tetgenmesh::decode_tet_only(tetrahedron ptr) 2554 | { 2555 | return (tetrahedron *) ((((uintptr_t) ptr) >> 4) << 4); 2556 | } 2557 | 2558 | inline int tetgenmesh::decode_ver_only(tetrahedron ptr) 2559 | { 2560 | return (int) ((uintptr_t) (ptr) & (uintptr_t) 15); 2561 | } 2562 | 2563 | // bond() connects two tetrahedra together. (t1,v1) and (t2,v2) must 2564 | // refer to the same face and the same edge. 2565 | 2566 | inline void tetgenmesh::bond(triface& t1, triface& t2) { 2567 | t1.tet[t1.ver & 3] = encode2(t2.tet, bondtbl[t1.ver][t2.ver]); 2568 | t2.tet[t2.ver & 3] = encode2(t1.tet, bondtbl[t2.ver][t1.ver]); 2569 | } 2570 | 2571 | 2572 | // dissolve() a bond (from one side). 2573 | 2574 | inline void tetgenmesh::dissolve(triface& t) { 2575 | t.tet[t.ver & 3] = NULL; 2576 | } 2577 | 2578 | // enext() finds the next edge (counterclockwise) in the same face. 2579 | 2580 | inline void tetgenmesh::enext(triface& t1, triface& t2) { 2581 | t2.tet = t1.tet; 2582 | t2.ver = enexttbl[t1.ver]; // (t1.ver + 4) % 12; 2583 | } 2584 | 2585 | inline void tetgenmesh::enextself(triface& t) { 2586 | t.ver = enexttbl[t.ver]; // (t.ver + 4) % 12; 2587 | } 2588 | 2589 | // eprev() finds the next edge (clockwise) in the same face. 2590 | 2591 | inline void tetgenmesh::eprev(triface& t1, triface& t2) { 2592 | t2.tet = t1.tet; 2593 | t2.ver = eprevtbl[t1.ver]; // (t1.ver + 8) % 12; 2594 | } 2595 | 2596 | inline void tetgenmesh::eprevself(triface& t) { 2597 | t.ver = eprevtbl[t.ver]; // (t.ver + 8) % 12; 2598 | } 2599 | 2600 | // esym() finds the reversed edge. It is in the other face of the 2601 | // same tetrahedron. 2602 | 2603 | inline void tetgenmesh::esym(triface& t1, triface& t2) { 2604 | (t2).tet = (t1).tet; 2605 | (t2).ver = esymtbl[(t1).ver]; 2606 | } 2607 | 2608 | inline void tetgenmesh::esymself(triface& t) { 2609 | (t).ver = esymtbl[(t).ver]; 2610 | } 2611 | 2612 | // enextesym() finds the reversed edge of the next edge. It is in the other 2613 | // face of the same tetrahedron. It is the combination esym() * enext(). 2614 | 2615 | inline void tetgenmesh::enextesym(triface& t1, triface& t2) { 2616 | t2.tet = t1.tet; 2617 | t2.ver = enextesymtbl[t1.ver]; 2618 | } 2619 | 2620 | inline void tetgenmesh::enextesymself(triface& t) { 2621 | t.ver = enextesymtbl[t.ver]; 2622 | } 2623 | 2624 | // eprevesym() finds the reversed edge of the previous edge. 2625 | 2626 | inline void tetgenmesh::eprevesym(triface& t1, triface& t2) { 2627 | t2.tet = t1.tet; 2628 | t2.ver = eprevesymtbl[t1.ver]; 2629 | } 2630 | 2631 | inline void tetgenmesh::eprevesymself(triface& t) { 2632 | t.ver = eprevesymtbl[t.ver]; 2633 | } 2634 | 2635 | // eorgoppo() Finds the opposite face of the origin of the current edge. 2636 | // Return the opposite edge of the current edge. 2637 | 2638 | inline void tetgenmesh::eorgoppo(triface& t1, triface& t2) { 2639 | t2.tet = t1.tet; 2640 | t2.ver = eorgoppotbl[t1.ver]; 2641 | } 2642 | 2643 | inline void tetgenmesh::eorgoppoself(triface& t) { 2644 | t.ver = eorgoppotbl[t.ver]; 2645 | } 2646 | 2647 | // edestoppo() Finds the opposite face of the destination of the current 2648 | // edge. Return the opposite edge of the current edge. 2649 | 2650 | inline void tetgenmesh::edestoppo(triface& t1, triface& t2) { 2651 | t2.tet = t1.tet; 2652 | t2.ver = edestoppotbl[t1.ver]; 2653 | } 2654 | 2655 | inline void tetgenmesh::edestoppoself(triface& t) { 2656 | t.ver = edestoppotbl[t.ver]; 2657 | } 2658 | 2659 | // fsym() finds the adjacent tetrahedron at the same face and the same edge. 2660 | 2661 | inline void tetgenmesh::fsym(triface& t1, triface& t2) { 2662 | decode((t1).tet[(t1).ver & 3], t2); 2663 | t2.ver = fsymtbl[t1.ver][t2.ver]; 2664 | } 2665 | 2666 | 2667 | #define fsymself(t) \ 2668 | t1ver = (t).ver; \ 2669 | decode((t).tet[(t).ver & 3], (t));\ 2670 | (t).ver = fsymtbl[t1ver][(t).ver] 2671 | 2672 | // fnext() finds the next face while rotating about an edge according to 2673 | // a right-hand rule. The face is in the adjacent tetrahedron. It is 2674 | // the combination: fsym() * esym(). 2675 | 2676 | inline void tetgenmesh::fnext(triface& t1, triface& t2) { 2677 | decode(t1.tet[facepivot1[t1.ver]], t2); 2678 | t2.ver = facepivot2[t1.ver][t2.ver]; 2679 | } 2680 | 2681 | 2682 | #define fnextself(t) \ 2683 | t1ver = (t).ver; \ 2684 | decode((t).tet[facepivot1[(t).ver]], (t)); \ 2685 | (t).ver = facepivot2[t1ver][(t).ver] 2686 | 2687 | 2688 | // The following primtives get or set the origin, destination, face apex, 2689 | // or face opposite of an ordered tetrahedron. 2690 | 2691 | inline tetgenmesh::point tetgenmesh::org(triface& t) { 2692 | return (point) (t).tet[orgpivot[(t).ver]]; 2693 | } 2694 | 2695 | inline tetgenmesh::point tetgenmesh:: dest(triface& t) { 2696 | return (point) (t).tet[destpivot[(t).ver]]; 2697 | } 2698 | 2699 | inline tetgenmesh::point tetgenmesh:: apex(triface& t) { 2700 | return (point) (t).tet[apexpivot[(t).ver]]; 2701 | } 2702 | 2703 | inline tetgenmesh::point tetgenmesh:: oppo(triface& t) { 2704 | return (point) (t).tet[oppopivot[(t).ver]]; 2705 | } 2706 | 2707 | inline void tetgenmesh:: setorg(triface& t, point p) { 2708 | (t).tet[orgpivot[(t).ver]] = (tetrahedron) (p); 2709 | } 2710 | 2711 | inline void tetgenmesh:: setdest(triface& t, point p) { 2712 | (t).tet[destpivot[(t).ver]] = (tetrahedron) (p); 2713 | } 2714 | 2715 | inline void tetgenmesh:: setapex(triface& t, point p) { 2716 | (t).tet[apexpivot[(t).ver]] = (tetrahedron) (p); 2717 | } 2718 | 2719 | inline void tetgenmesh:: setoppo(triface& t, point p) { 2720 | (t).tet[oppopivot[(t).ver]] = (tetrahedron) (p); 2721 | } 2722 | 2723 | #define setvertices(t, torg, tdest, tapex, toppo) \ 2724 | (t).tet[orgpivot[(t).ver]] = (tetrahedron) (torg);\ 2725 | (t).tet[destpivot[(t).ver]] = (tetrahedron) (tdest); \ 2726 | (t).tet[apexpivot[(t).ver]] = (tetrahedron) (tapex); \ 2727 | (t).tet[oppopivot[(t).ver]] = (tetrahedron) (toppo) 2728 | 2729 | 2730 | inline REAL* tetgenmesh::get_polar(tetrahedron* ptr) 2731 | { 2732 | return &(((REAL *) (ptr))[polarindex]); 2733 | } 2734 | inline REAL tetgenmesh::get_volume(tetrahedron* ptr) 2735 | { 2736 | return ((REAL *) (ptr))[polarindex + 4]; 2737 | } 2738 | 2739 | // Check or set a tetrahedron's attributes. 2740 | 2741 | inline REAL tetgenmesh::elemattribute(tetrahedron* ptr, int attnum) { 2742 | return ((REAL *) (ptr))[elemattribindex + attnum]; 2743 | } 2744 | 2745 | inline void tetgenmesh::setelemattribute(tetrahedron* ptr, int attnum, 2746 | REAL value) { 2747 | ((REAL *) (ptr))[elemattribindex + attnum] = value; 2748 | } 2749 | 2750 | // Check or set a tetrahedron's maximum volume bound. 2751 | 2752 | inline REAL tetgenmesh::volumebound(tetrahedron* ptr) { 2753 | return ((REAL *) (ptr))[volumeboundindex]; 2754 | } 2755 | 2756 | inline void tetgenmesh::setvolumebound(tetrahedron* ptr, REAL value) { 2757 | ((REAL *) (ptr))[volumeboundindex] = value; 2758 | } 2759 | 2760 | // Get or set a tetrahedron's index (only used for output). 2761 | // These two routines use the reserved slot ptr[10]. 2762 | 2763 | inline int tetgenmesh::elemindex(tetrahedron* ptr) { 2764 | int *iptr = (int *) &(ptr[10]); 2765 | return iptr[0]; 2766 | } 2767 | 2768 | inline void tetgenmesh::setelemindex(tetrahedron* ptr, int value) { 2769 | int *iptr = (int *) &(ptr[10]); 2770 | iptr[0] = value; 2771 | } 2772 | 2773 | // Get or set a tetrahedron's marker. 2774 | // Set 'value = 0' cleans all the face/edge flags. 2775 | 2776 | inline int tetgenmesh::elemmarker(tetrahedron* ptr) { 2777 | return ((int *) (ptr))[elemmarkerindex]; 2778 | } 2779 | 2780 | inline void tetgenmesh::setelemmarker(tetrahedron* ptr, int value) { 2781 | ((int *) (ptr))[elemmarkerindex] = value; 2782 | } 2783 | 2784 | // infect(), infected(), uninfect() -- primitives to flag or unflag a 2785 | // tetrahedron. The last bit of the element marker is flagged (1) 2786 | // or unflagged (0). 2787 | 2788 | inline void tetgenmesh::infect(triface& t) { 2789 | ((int *) (t.tet))[elemmarkerindex] |= 1; 2790 | } 2791 | 2792 | inline void tetgenmesh::uninfect(triface& t) { 2793 | ((int *) (t.tet))[elemmarkerindex] &= ~1; 2794 | } 2795 | 2796 | inline bool tetgenmesh::infected(triface& t) { 2797 | return (((int *) (t.tet))[elemmarkerindex] & 1) != 0; 2798 | } 2799 | 2800 | // marktest(), marktested(), unmarktest() -- primitives to flag or unflag a 2801 | // tetrahedron. Use the second lowerest bit of the element marker. 2802 | 2803 | inline void tetgenmesh::marktest(triface& t) { 2804 | ((int *) (t.tet))[elemmarkerindex] |= 2; 2805 | } 2806 | 2807 | inline void tetgenmesh::unmarktest(triface& t) { 2808 | ((int *) (t.tet))[elemmarkerindex] &= ~2; 2809 | } 2810 | 2811 | inline bool tetgenmesh::marktested(triface& t) { 2812 | return (((int *) (t.tet))[elemmarkerindex] & 2) != 0; 2813 | } 2814 | 2815 | // markface(), unmarkface(), facemarked() -- primitives to flag or unflag a 2816 | // face of a tetrahedron. From the last 3rd to 6th bits are used for 2817 | // face markers, e.g., the last third bit corresponds to loc = 0. 2818 | 2819 | inline void tetgenmesh::markface(triface& t) { 2820 | ((int *) (t.tet))[elemmarkerindex] |= (4 << (t.ver & 3)); 2821 | } 2822 | 2823 | inline void tetgenmesh::unmarkface(triface& t) { 2824 | ((int *) (t.tet))[elemmarkerindex] &= ~(4 << (t.ver & 3)); 2825 | } 2826 | 2827 | inline bool tetgenmesh::facemarked(triface& t) { 2828 | return (((int *) (t.tet))[elemmarkerindex] & (4 << (t.ver & 3))) != 0; 2829 | } 2830 | 2831 | // markedge(), unmarkedge(), edgemarked() -- primitives to flag or unflag an 2832 | // edge of a tetrahedron. From the last 7th to 12th bits are used for 2833 | // edge markers, e.g., the last 7th bit corresponds to the 0th edge, etc. 2834 | // Remark: The last 7th bit is marked by 2^6 = 64. 2835 | 2836 | inline void tetgenmesh::markedge(triface& t) { 2837 | ((int *) (t.tet))[elemmarkerindex] |= (int) (64 << ver2edge[(t).ver]); 2838 | } 2839 | 2840 | inline void tetgenmesh::unmarkedge(triface& t) { 2841 | ((int *) (t.tet))[elemmarkerindex] &= ~(int) (64 << ver2edge[(t).ver]); 2842 | } 2843 | 2844 | inline bool tetgenmesh::edgemarked(triface& t) { 2845 | return (((int *) (t.tet))[elemmarkerindex] & 2846 | (int) (64 << ver2edge[(t).ver])) != 0; 2847 | } 2848 | 2849 | // marktest2(), unmarktest2(), marktest2ed() -- primitives to flag and unflag 2850 | // a tetrahedron. The 13th bit (2^12 = 4096) is used for this flag. 2851 | 2852 | inline void tetgenmesh::marktest2(triface& t) { 2853 | ((int *) (t.tet))[elemmarkerindex] |= (int) (4096); 2854 | } 2855 | 2856 | inline void tetgenmesh::unmarktest2(triface& t) { 2857 | ((int *) (t.tet))[elemmarkerindex] &= ~(int) (4096); 2858 | } 2859 | 2860 | inline bool tetgenmesh::marktest2ed(triface& t) { 2861 | return (((int *) (t.tet))[elemmarkerindex] & (int) (4096)) != 0; 2862 | } 2863 | 2864 | // elemcounter(), setelemcounter() -- primitives to read or ser a (small) 2865 | // integer counter in this tet. It is saved from the 16th bit. On 32 bit 2866 | // system, the range of the counter is [0, 2^15 = 32768]. 2867 | 2868 | inline int tetgenmesh::elemcounter(triface& t) { 2869 | return (((int *) (t.tet))[elemmarkerindex]) >> 16; 2870 | } 2871 | 2872 | inline void tetgenmesh::setelemcounter(triface& t, int value) { 2873 | int c = ((int *) (t.tet))[elemmarkerindex]; 2874 | // Clear the old counter while keep the other flags. 2875 | c &= 65535; // sum_{i=0^15} 2^i 2876 | c |= (value << 16); 2877 | ((int *) (t.tet))[elemmarkerindex] = c; 2878 | } 2879 | 2880 | inline void tetgenmesh::increaseelemcounter(triface& t) { 2881 | int c = elemcounter(t); 2882 | setelemcounter(t, c + 1); 2883 | } 2884 | 2885 | inline void tetgenmesh::decreaseelemcounter(triface& t) { 2886 | int c = elemcounter(t); 2887 | setelemcounter(t, c - 1); 2888 | } 2889 | 2890 | // ishulltet() tests if t is a hull tetrahedron. 2891 | 2892 | inline bool tetgenmesh::ishulltet(triface& t) { 2893 | return (point) (t).tet[7] == dummypoint; 2894 | } 2895 | 2896 | // isdeadtet() tests if t is a tetrahedron is dead. 2897 | 2898 | inline bool tetgenmesh::isdeadtet(triface& t) { 2899 | return ((t.tet == NULL) || (t.tet[4] == NULL)); 2900 | } 2901 | 2902 | //============================================================================// 2903 | // // 2904 | // Primitives for subfaces and subsegments // 2905 | // // 2906 | //============================================================================// 2907 | 2908 | // Each subface contains three pointers to its neighboring subfaces, with 2909 | // edge versions. To save memory, both information are kept in a single 2910 | // pointer. To make this possible, all subfaces are aligned to eight-byte 2911 | // boundaries, so that the last three bits of each pointer are zeros. An 2912 | // edge version (in the range 0 to 5) is compressed into the last three 2913 | // bits of each pointer by 'sencode()'. 'sdecode()' decodes a pointer, 2914 | // extracting an edge version and a pointer to the beginning of a subface. 2915 | 2916 | inline void tetgenmesh::sdecode(shellface sptr, face& s) { 2917 | s.shver = (int) ((uintptr_t) (sptr) & (uintptr_t) 7); 2918 | s.sh = (shellface *) ((uintptr_t) (sptr) ^ (uintptr_t) (s.shver)); 2919 | } 2920 | 2921 | inline tetgenmesh::shellface tetgenmesh::sencode(face& s) { 2922 | return (shellface) ((uintptr_t) s.sh | (uintptr_t) s.shver); 2923 | } 2924 | 2925 | inline tetgenmesh::shellface tetgenmesh::sencode2(shellface *sh, int shver) { 2926 | return (shellface) ((uintptr_t) sh | (uintptr_t) shver); 2927 | } 2928 | 2929 | // sbond() bonds two subfaces (s1) and (s2) together. s1 and s2 must refer 2930 | // to the same edge. No requirement is needed on their orientations. 2931 | 2932 | inline void tetgenmesh::sbond(face& s1, face& s2) 2933 | { 2934 | s1.sh[s1.shver >> 1] = sencode(s2); 2935 | s2.sh[s2.shver >> 1] = sencode(s1); 2936 | } 2937 | 2938 | // sbond1() bonds s1 <== s2, i.e., after bonding, s1 is pointing to s2, 2939 | // but s2 is not pointing to s1. s1 and s2 must refer to the same edge. 2940 | // No requirement is needed on their orientations. 2941 | 2942 | inline void tetgenmesh::sbond1(face& s1, face& s2) 2943 | { 2944 | s1.sh[s1.shver >> 1] = sencode(s2); 2945 | } 2946 | 2947 | // Dissolve a subface bond (from one side). Note that the other subface 2948 | // will still think it's connected to this subface. 2949 | 2950 | inline void tetgenmesh::sdissolve(face& s) 2951 | { 2952 | s.sh[s.shver >> 1] = NULL; 2953 | } 2954 | 2955 | // spivot() finds the adjacent subface (s2) for a given subface (s1). 2956 | // s1 and s2 share at the same edge. 2957 | 2958 | inline void tetgenmesh::spivot(face& s1, face& s2) 2959 | { 2960 | shellface sptr = s1.sh[s1.shver >> 1]; 2961 | sdecode(sptr, s2); 2962 | } 2963 | 2964 | inline void tetgenmesh::spivotself(face& s) 2965 | { 2966 | shellface sptr = s.sh[s.shver >> 1]; 2967 | sdecode(sptr, s); 2968 | } 2969 | 2970 | // These primitives determine or set the origin, destination, or apex 2971 | // of a subface with respect to the edge version. 2972 | 2973 | inline tetgenmesh::point tetgenmesh::sorg(face& s) 2974 | { 2975 | return (point) s.sh[sorgpivot[s.shver]]; 2976 | } 2977 | 2978 | inline tetgenmesh::point tetgenmesh::sdest(face& s) 2979 | { 2980 | return (point) s.sh[sdestpivot[s.shver]]; 2981 | } 2982 | 2983 | inline tetgenmesh::point tetgenmesh::sapex(face& s) 2984 | { 2985 | return (point) s.sh[sapexpivot[s.shver]]; 2986 | } 2987 | 2988 | inline void tetgenmesh::setsorg(face& s, point pointptr) 2989 | { 2990 | s.sh[sorgpivot[s.shver]] = (shellface) pointptr; 2991 | } 2992 | 2993 | inline void tetgenmesh::setsdest(face& s, point pointptr) 2994 | { 2995 | s.sh[sdestpivot[s.shver]] = (shellface) pointptr; 2996 | } 2997 | 2998 | inline void tetgenmesh::setsapex(face& s, point pointptr) 2999 | { 3000 | s.sh[sapexpivot[s.shver]] = (shellface) pointptr; 3001 | } 3002 | 3003 | #define setshvertices(s, pa, pb, pc)\ 3004 | setsorg(s, pa);\ 3005 | setsdest(s, pb);\ 3006 | setsapex(s, pc) 3007 | 3008 | // sesym() reserves the direction of the lead edge. 3009 | 3010 | inline void tetgenmesh::sesym(face& s1, face& s2) 3011 | { 3012 | s2.sh = s1.sh; 3013 | s2.shver = (s1.shver ^ 1); // Inverse the last bit. 3014 | } 3015 | 3016 | inline void tetgenmesh::sesymself(face& s) 3017 | { 3018 | s.shver ^= 1; 3019 | } 3020 | 3021 | // senext() finds the next edge (counterclockwise) in the same orientation 3022 | // of this face. 3023 | 3024 | inline void tetgenmesh::senext(face& s1, face& s2) 3025 | { 3026 | s2.sh = s1.sh; 3027 | s2.shver = snextpivot[s1.shver]; 3028 | } 3029 | 3030 | inline void tetgenmesh::senextself(face& s) 3031 | { 3032 | s.shver = snextpivot[s.shver]; 3033 | } 3034 | 3035 | inline void tetgenmesh::senext2(face& s1, face& s2) 3036 | { 3037 | s2.sh = s1.sh; 3038 | s2.shver = snextpivot[snextpivot[s1.shver]]; 3039 | } 3040 | 3041 | inline void tetgenmesh::senext2self(face& s) 3042 | { 3043 | s.shver = snextpivot[snextpivot[s.shver]]; 3044 | } 3045 | 3046 | 3047 | // Check or set a subface's maximum area bound. 3048 | 3049 | inline REAL tetgenmesh::areabound(face& s) 3050 | { 3051 | return ((REAL *) (s.sh))[areaboundindex]; 3052 | } 3053 | 3054 | inline void tetgenmesh::setareabound(face& s, REAL value) 3055 | { 3056 | ((REAL *) (s.sh))[areaboundindex] = value; 3057 | } 3058 | 3059 | // These two primitives read or set a shell marker. Shell markers are used 3060 | // to hold user boundary information. 3061 | 3062 | inline int tetgenmesh::shellmark(face& s) 3063 | { 3064 | return ((int *) (s.sh))[shmarkindex]; 3065 | } 3066 | 3067 | inline void tetgenmesh::setshellmark(face& s, int value) 3068 | { 3069 | ((int *) (s.sh))[shmarkindex] = value; 3070 | } 3071 | 3072 | 3073 | 3074 | // sinfect(), sinfected(), suninfect() -- primitives to flag or unflag a 3075 | // subface. The last bit of ((int *) ((s).sh))[shmarkindex+1] is flagged. 3076 | 3077 | inline void tetgenmesh::sinfect(face& s) 3078 | { 3079 | ((int *) ((s).sh))[shmarkindex+1] = 3080 | (((int *) ((s).sh))[shmarkindex+1] | (int) 1); 3081 | } 3082 | 3083 | inline void tetgenmesh::suninfect(face& s) 3084 | { 3085 | ((int *) ((s).sh))[shmarkindex+1] = 3086 | (((int *) ((s).sh))[shmarkindex+1] & ~(int) 1); 3087 | } 3088 | 3089 | // Test a subface for viral infection. 3090 | 3091 | inline bool tetgenmesh::sinfected(face& s) 3092 | { 3093 | return (((int *) ((s).sh))[shmarkindex+1] & (int) 1) != 0; 3094 | } 3095 | 3096 | // smarktest(), smarktested(), sunmarktest() -- primitives to flag or unflag 3097 | // a subface. The last 2nd bit of the integer is flagged. 3098 | 3099 | inline void tetgenmesh::smarktest(face& s) 3100 | { 3101 | ((int *) ((s).sh))[shmarkindex+1] = 3102 | (((int *)((s).sh))[shmarkindex+1] | (int) 2); 3103 | } 3104 | 3105 | inline void tetgenmesh::sunmarktest(face& s) 3106 | { 3107 | ((int *) ((s).sh))[shmarkindex+1] = 3108 | (((int *)((s).sh))[shmarkindex+1] & ~(int)2); 3109 | } 3110 | 3111 | inline bool tetgenmesh::smarktested(face& s) 3112 | { 3113 | return ((((int *) ((s).sh))[shmarkindex+1] & (int) 2) != 0); 3114 | } 3115 | 3116 | // smarktest2(), smarktest2ed(), sunmarktest2() -- primitives to flag or 3117 | // unflag a subface. The last 3rd bit of the integer is flagged. 3118 | 3119 | inline void tetgenmesh::smarktest2(face& s) 3120 | { 3121 | ((int *) ((s).sh))[shmarkindex+1] = 3122 | (((int *)((s).sh))[shmarkindex+1] | (int) 4); 3123 | } 3124 | 3125 | inline void tetgenmesh::sunmarktest2(face& s) 3126 | { 3127 | ((int *) ((s).sh))[shmarkindex+1] = 3128 | (((int *)((s).sh))[shmarkindex+1] & ~(int)4); 3129 | } 3130 | 3131 | inline bool tetgenmesh::smarktest2ed(face& s) 3132 | { 3133 | return ((((int *) ((s).sh))[shmarkindex+1] & (int) 4) != 0); 3134 | } 3135 | 3136 | // The last 4th bit of ((int *) ((s).sh))[shmarkindex+1] is flagged. 3137 | 3138 | inline void tetgenmesh::smarktest3(face& s) 3139 | { 3140 | ((int *) ((s).sh))[shmarkindex+1] = 3141 | (((int *)((s).sh))[shmarkindex+1] | (int) 8); 3142 | } 3143 | 3144 | inline void tetgenmesh::sunmarktest3(face& s) 3145 | { 3146 | ((int *) ((s).sh))[shmarkindex+1] = 3147 | (((int *)((s).sh))[shmarkindex+1] & ~(int)8); 3148 | } 3149 | 3150 | inline bool tetgenmesh::smarktest3ed(face& s) 3151 | { 3152 | return ((((int *) ((s).sh))[shmarkindex+1] & (int) 8) != 0); 3153 | } 3154 | 3155 | 3156 | // Each facet has a unique index (automatically indexed). Starting from '0'. 3157 | // We save this index in the same field of the shell type. 3158 | 3159 | inline void tetgenmesh::setfacetindex(face& s, int value) 3160 | { 3161 | ((int *) (s.sh))[shmarkindex + 2] = value; 3162 | } 3163 | 3164 | inline int tetgenmesh::getfacetindex(face& s) 3165 | { 3166 | return ((int *) (s.sh))[shmarkindex + 2]; 3167 | } 3168 | 3169 | // Tests if the subface (subsegment) s is dead. 3170 | 3171 | inline bool tetgenmesh::isdeadsh(face& s) { 3172 | return ((s.sh == NULL) || (s.sh[3] == NULL)); 3173 | } 3174 | 3175 | //============================================================================// 3176 | // // 3177 | // Primitives for interacting between tetrahedra and subfaces // 3178 | // // 3179 | //============================================================================// 3180 | 3181 | // tsbond() bond a tetrahedron (t) and a subface (s) together. 3182 | // Note that t and s must be the same face and the same edge. Moreover, 3183 | // t and s have the same orientation. 3184 | // Since the edge number in t and in s can be any number in {0,1,2}. We bond 3185 | // the edge in s which corresponds to t's 0th edge, and vice versa. 3186 | 3187 | inline void tetgenmesh::tsbond(triface& t, face& s) 3188 | { 3189 | if ((t).tet[9] == NULL) { 3190 | // Allocate space for this tet. 3191 | (t).tet[9] = (tetrahedron) tet2subpool->alloc(); 3192 | // Initialize. 3193 | for (int i = 0; i < 4; i++) { 3194 | ((shellface *) (t).tet[9])[i] = NULL; 3195 | } 3196 | } 3197 | // Bond t <== s. 3198 | ((shellface *) (t).tet[9])[(t).ver & 3] = 3199 | sencode2((s).sh, tsbondtbl[t.ver][s.shver]); 3200 | // Bond s <== t. 3201 | s.sh[9 + ((s).shver & 1)] = 3202 | (shellface) encode2((t).tet, stbondtbl[t.ver][s.shver]); 3203 | } 3204 | 3205 | // tspivot() finds a subface (s) abutting on the given tetrahdera (t). 3206 | // Return s.sh = NULL if there is no subface at t. Otherwise, return 3207 | // the subface s, and s and t must be at the same edge wth the same 3208 | // orientation. 3209 | 3210 | inline void tetgenmesh::tspivot(triface& t, face& s) 3211 | { 3212 | if ((t).tet[9] == NULL) { 3213 | (s).sh = NULL; 3214 | return; 3215 | } 3216 | // Get the attached subface s. 3217 | sdecode(((shellface *) (t).tet[9])[(t).ver & 3], (s)); 3218 | (s).shver = tspivottbl[t.ver][s.shver]; 3219 | } 3220 | 3221 | // Quickly check if the handle (t, v) is a subface. 3222 | #define issubface(t) \ 3223 | ((t).tet[9] && ((t).tet[9])[(t).ver & 3]) 3224 | 3225 | // stpivot() finds a tetrahedron (t) abutting a given subface (s). 3226 | // Return the t (if it exists) with the same edge and the same 3227 | // orientation of s. 3228 | 3229 | inline void tetgenmesh::stpivot(face& s, triface& t) 3230 | { 3231 | decode((tetrahedron) s.sh[9 + (s.shver & 1)], t); 3232 | if ((t).tet == NULL) { 3233 | return; 3234 | } 3235 | (t).ver = stpivottbl[t.ver][s.shver]; 3236 | } 3237 | 3238 | // Quickly check if this subface is attached to a tetrahedron. 3239 | 3240 | #define isshtet(s) \ 3241 | ((s).sh[9 + ((s).shver & 1)]) 3242 | 3243 | // tsdissolve() dissolve a bond (from the tetrahedron side). 3244 | 3245 | inline void tetgenmesh::tsdissolve(triface& t) 3246 | { 3247 | if ((t).tet[9] != NULL) { 3248 | ((shellface *) (t).tet[9])[(t).ver & 3] = NULL; 3249 | } 3250 | } 3251 | 3252 | // stdissolve() dissolve a bond (from the subface side). 3253 | 3254 | inline void tetgenmesh::stdissolve(face& s) 3255 | { 3256 | (s).sh[9] = NULL; 3257 | (s).sh[10] = NULL; 3258 | } 3259 | 3260 | //============================================================================// 3261 | // // 3262 | // Primitives for interacting between subfaces and segments // 3263 | // // 3264 | //============================================================================// 3265 | 3266 | // ssbond() bond a subface to a subsegment. 3267 | 3268 | inline void tetgenmesh::ssbond(face& s, face& edge) 3269 | { 3270 | s.sh[6 + (s.shver >> 1)] = sencode(edge); 3271 | edge.sh[0] = sencode(s); 3272 | } 3273 | 3274 | inline void tetgenmesh::ssbond1(face& s, face& edge) 3275 | { 3276 | s.sh[6 + (s.shver >> 1)] = sencode(edge); 3277 | //edge.sh[0] = sencode(s); 3278 | } 3279 | 3280 | // ssdisolve() dissolve a bond (from the subface side) 3281 | 3282 | inline void tetgenmesh::ssdissolve(face& s) 3283 | { 3284 | s.sh[6 + (s.shver >> 1)] = NULL; 3285 | } 3286 | 3287 | // sspivot() finds a subsegment abutting a subface. 3288 | 3289 | inline void tetgenmesh::sspivot(face& s, face& edge) 3290 | { 3291 | sdecode((shellface) s.sh[6 + (s.shver >> 1)], edge); 3292 | } 3293 | 3294 | // Quickly check if the edge is a subsegment. 3295 | 3296 | #define isshsubseg(s) \ 3297 | ((s).sh[6 + ((s).shver >> 1)]) 3298 | 3299 | //============================================================================// 3300 | // // 3301 | // Primitives for interacting between tetrahedra and segments // 3302 | // // 3303 | //============================================================================// 3304 | 3305 | inline void tetgenmesh::tssbond1(triface& t, face& s) 3306 | { 3307 | if ((t).tet[8] == NULL) { 3308 | // Allocate space for this tet. 3309 | (t).tet[8] = (tetrahedron) tet2segpool->alloc(); 3310 | // Initialization. 3311 | for (int i = 0; i < 6; i++) { 3312 | ((shellface *) (t).tet[8])[i] = NULL; 3313 | } 3314 | } 3315 | ((shellface *) (t).tet[8])[ver2edge[(t).ver]] = sencode((s)); 3316 | } 3317 | 3318 | inline void tetgenmesh::sstbond1(face& s, triface& t) 3319 | { 3320 | ((tetrahedron *) (s).sh)[9] = encode(t); 3321 | } 3322 | 3323 | inline void tetgenmesh::tssdissolve1(triface& t) 3324 | { 3325 | if ((t).tet[8] != NULL) { 3326 | ((shellface *) (t).tet[8])[ver2edge[(t).ver]] = NULL; 3327 | } 3328 | } 3329 | 3330 | inline void tetgenmesh::sstdissolve1(face& s) 3331 | { 3332 | ((tetrahedron *) (s).sh)[9] = NULL; 3333 | } 3334 | 3335 | inline void tetgenmesh::tsspivot1(triface& t, face& s) 3336 | { 3337 | if ((t).tet[8] != NULL) { 3338 | sdecode(((shellface *) (t).tet[8])[ver2edge[(t).ver]], s); 3339 | } else { 3340 | (s).sh = NULL; 3341 | } 3342 | } 3343 | 3344 | // Quickly check whether 't' is a segment or not. 3345 | 3346 | #define issubseg(t) \ 3347 | ((t).tet[8] && ((t).tet[8])[ver2edge[(t).ver]]) 3348 | 3349 | inline void tetgenmesh::sstpivot1(face& s, triface& t) 3350 | { 3351 | decode((tetrahedron) s.sh[9], t); 3352 | } 3353 | 3354 | //============================================================================// 3355 | // // 3356 | // Primitives for points // 3357 | // // 3358 | //============================================================================// 3359 | 3360 | inline int tetgenmesh::pointmark(point pt) { 3361 | return ((int *) (pt))[pointmarkindex]; 3362 | } 3363 | 3364 | inline void tetgenmesh::setpointmark(point pt, int value) { 3365 | ((int *) (pt))[pointmarkindex] = value; 3366 | } 3367 | 3368 | 3369 | // These two primitives set and read the type of the point. 3370 | 3371 | inline enum tetgenmesh::verttype tetgenmesh::pointtype(point pt) { 3372 | return (enum verttype) (((int *) (pt))[pointmarkindex + 1] >> (int) 8); 3373 | } 3374 | 3375 | inline void tetgenmesh::setpointtype(point pt, enum verttype value) { 3376 | ((int *) (pt))[pointmarkindex + 1] = 3377 | ((int) value << 8) + (((int *) (pt))[pointmarkindex + 1] & (int) 255); 3378 | } 3379 | 3380 | // pinfect(), puninfect(), pinfected() -- primitives to flag or unflag 3381 | // a point. The last bit of the integer '[pointindex+1]' is flagged. 3382 | 3383 | inline void tetgenmesh::pinfect(point pt) { 3384 | ((int *) (pt))[pointmarkindex + 1] |= (int) 1; 3385 | } 3386 | 3387 | inline void tetgenmesh::puninfect(point pt) { 3388 | ((int *) (pt))[pointmarkindex + 1] &= ~(int) 1; 3389 | } 3390 | 3391 | inline bool tetgenmesh::pinfected(point pt) { 3392 | return (((int *) (pt))[pointmarkindex + 1] & (int) 1) != 0; 3393 | } 3394 | 3395 | // pmarktest(), punmarktest(), pmarktested() -- more primitives to 3396 | // flag or unflag a point. 3397 | 3398 | inline void tetgenmesh::pmarktest(point pt) { 3399 | ((int *) (pt))[pointmarkindex + 1] |= (int) 2; 3400 | } 3401 | 3402 | inline void tetgenmesh::punmarktest(point pt) { 3403 | ((int *) (pt))[pointmarkindex + 1] &= ~(int) 2; 3404 | } 3405 | 3406 | inline bool tetgenmesh::pmarktested(point pt) { 3407 | return (((int *) (pt))[pointmarkindex + 1] & (int) 2) != 0; 3408 | } 3409 | 3410 | inline void tetgenmesh::pmarktest2(point pt) { 3411 | ((int *) (pt))[pointmarkindex + 1] |= (int) 4; 3412 | } 3413 | 3414 | inline void tetgenmesh::punmarktest2(point pt) { 3415 | ((int *) (pt))[pointmarkindex + 1] &= ~(int) 4; 3416 | } 3417 | 3418 | inline bool tetgenmesh::pmarktest2ed(point pt) { 3419 | return (((int *) (pt))[pointmarkindex + 1] & (int) 4) != 0; 3420 | } 3421 | 3422 | inline void tetgenmesh::pmarktest3(point pt) { 3423 | ((int *) (pt))[pointmarkindex + 1] |= (int) 8; 3424 | } 3425 | 3426 | inline void tetgenmesh::punmarktest3(point pt) { 3427 | ((int *) (pt))[pointmarkindex + 1] &= ~(int) 8; 3428 | } 3429 | 3430 | inline bool tetgenmesh::pmarktest3ed(point pt) { 3431 | return (((int *) (pt))[pointmarkindex + 1] & (int) 8) != 0; 3432 | } 3433 | 3434 | // Read and set the geometry tag of the point (used by -s option). 3435 | 3436 | inline int tetgenmesh::pointgeomtag(point pt) { 3437 | return ((int *) (pt))[pointmarkindex + 2]; 3438 | } 3439 | 3440 | inline void tetgenmesh::setpointgeomtag(point pt, int value) { 3441 | ((int *) (pt))[pointmarkindex + 2] = value; 3442 | } 3443 | 3444 | // Read and set the u,v coordinates of the point (used by -s option). 3445 | 3446 | inline REAL tetgenmesh::pointgeomuv(point pt, int i) { 3447 | return pt[pointparamindex + i]; 3448 | } 3449 | 3450 | inline void tetgenmesh::setpointgeomuv(point pt, int i, REAL value) { 3451 | pt[pointparamindex + i] = value; 3452 | } 3453 | 3454 | 3455 | 3456 | // These following primitives set and read a pointer to a tetrahedron 3457 | // a subface/subsegment, a point, or a tet of background mesh. 3458 | 3459 | inline tetgenmesh::tetrahedron tetgenmesh::point2tet(point pt) { 3460 | return ((tetrahedron *) (pt))[point2simindex]; 3461 | } 3462 | 3463 | inline void tetgenmesh::setpoint2tet(point pt, tetrahedron value) { 3464 | ((tetrahedron *) (pt))[point2simindex] = value; 3465 | } 3466 | 3467 | inline tetgenmesh::point tetgenmesh::point2ppt(point pt) { 3468 | return (point) ((tetrahedron *) (pt))[point2simindex + 1]; 3469 | } 3470 | 3471 | inline void tetgenmesh::setpoint2ppt(point pt, point value) { 3472 | ((tetrahedron *) (pt))[point2simindex + 1] = (tetrahedron) value; 3473 | } 3474 | 3475 | inline tetgenmesh::shellface tetgenmesh::point2sh(point pt) { 3476 | return (shellface) ((tetrahedron *) (pt))[point2simindex + 2]; 3477 | } 3478 | 3479 | inline void tetgenmesh::setpoint2sh(point pt, shellface value) { 3480 | ((tetrahedron *) (pt))[point2simindex + 2] = (tetrahedron) value; 3481 | } 3482 | 3483 | 3484 | inline tetgenmesh::tetrahedron tetgenmesh::point2bgmtet(point pt) { 3485 | return ((tetrahedron *) (pt))[point2simindex + 3]; 3486 | } 3487 | 3488 | inline void tetgenmesh::setpoint2bgmtet(point pt, tetrahedron value) { 3489 | ((tetrahedron *) (pt))[point2simindex + 3] = value; 3490 | } 3491 | 3492 | 3493 | // The primitives for saving and getting the insertion radius. 3494 | inline void tetgenmesh::setpointinsradius(point pt, REAL value) 3495 | { 3496 | pt[pointinsradiusindex] = value; 3497 | } 3498 | 3499 | inline REAL tetgenmesh::getpointinsradius(point pt) 3500 | { 3501 | return pt[pointinsradiusindex]; 3502 | } 3503 | 3504 | inline bool tetgenmesh::issteinerpoint(point pt) { 3505 | return (pointtype(pt) == FREESEGVERTEX) || (pointtype(pt) == FREEFACETVERTEX) 3506 | || (pointtype(pt) == FREEVOLVERTEX); 3507 | } 3508 | 3509 | // point2tetorg() Get the tetrahedron whose origin is the point. 3510 | 3511 | inline void tetgenmesh::point2tetorg(point pa, triface& searchtet) 3512 | { 3513 | decode(point2tet(pa), searchtet); 3514 | if ((point) searchtet.tet[4] == pa) { 3515 | searchtet.ver = 11; 3516 | } else if ((point) searchtet.tet[5] == pa) { 3517 | searchtet.ver = 3; 3518 | } else if ((point) searchtet.tet[6] == pa) { 3519 | searchtet.ver = 7; 3520 | } else { 3521 | searchtet.ver = 0; 3522 | } 3523 | } 3524 | 3525 | // point2shorg() Get the subface/segment whose origin is the point. 3526 | 3527 | inline void tetgenmesh::point2shorg(point pa, face& searchsh) 3528 | { 3529 | sdecode(point2sh(pa), searchsh); 3530 | if ((point) searchsh.sh[3] == pa) { 3531 | searchsh.shver = 0; 3532 | } else if ((point) searchsh.sh[4] == pa) { 3533 | searchsh.shver = (searchsh.sh[5] != NULL ? 2 : 1); 3534 | } else { 3535 | searchsh.shver = 4; 3536 | } 3537 | } 3538 | 3539 | // farsorg() Return the origin of the subsegment. 3540 | // farsdest() Return the destination of the subsegment. 3541 | 3542 | inline tetgenmesh::point tetgenmesh::farsorg(face& s) 3543 | { 3544 | face travesh, neighsh; 3545 | 3546 | travesh = s; 3547 | while (1) { 3548 | senext2(travesh, neighsh); 3549 | spivotself(neighsh); 3550 | if (neighsh.sh == NULL) break; 3551 | if (sorg(neighsh) != sorg(travesh)) sesymself(neighsh); 3552 | senext2(neighsh, travesh); 3553 | } 3554 | return sorg(travesh); 3555 | } 3556 | 3557 | inline tetgenmesh::point tetgenmesh::farsdest(face& s) 3558 | { 3559 | face travesh, neighsh; 3560 | 3561 | travesh = s; 3562 | while (1) { 3563 | senext(travesh, neighsh); 3564 | spivotself(neighsh); 3565 | if (neighsh.sh == NULL) break; 3566 | if (sdest(neighsh) != sdest(travesh)) sesymself(neighsh); 3567 | senext(neighsh, travesh); 3568 | } 3569 | return sdest(travesh); 3570 | } 3571 | 3572 | /////////////////////////////////////////////////////////////////////////////// 3573 | // // 3574 | // Linear algebra operators. // 3575 | // // 3576 | /////////////////////////////////////////////////////////////////////////////// 3577 | 3578 | // dot() returns the dot product: v1 dot v2. 3579 | inline REAL tetgenmesh::dot(REAL* v1, REAL* v2) 3580 | { 3581 | return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; 3582 | } 3583 | 3584 | // cross() computes the cross product: n = v1 cross v2. 3585 | inline void tetgenmesh::cross(REAL* v1, REAL* v2, REAL* n) 3586 | { 3587 | n[0] = v1[1] * v2[2] - v2[1] * v1[2]; 3588 | n[1] = -(v1[0] * v2[2] - v2[0] * v1[2]); 3589 | n[2] = v1[0] * v2[1] - v2[0] * v1[1]; 3590 | } 3591 | 3592 | // distance() computes the Euclidean distance between two points. 3593 | inline REAL tetgenmesh::distance(REAL* p1, REAL* p2) 3594 | { 3595 | return sqrt((p2[0] - p1[0]) * (p2[0] - p1[0]) + 3596 | (p2[1] - p1[1]) * (p2[1] - p1[1]) + 3597 | (p2[2] - p1[2]) * (p2[2] - p1[2])); 3598 | } 3599 | 3600 | inline REAL tetgenmesh::distance2(REAL* p1, REAL* p2) 3601 | { 3602 | return norm2(p2[0] - p1[0], p2[1] - p1[1], p2[2] - p1[2]); 3603 | } 3604 | 3605 | inline REAL tetgenmesh::norm2(REAL x, REAL y, REAL z) 3606 | { 3607 | return (x) * (x) + (y) * (y) + (z) * (z); 3608 | } 3609 | 3610 | 3611 | 3612 | #endif // #ifndef tetgenH 3613 | 3614 | --------------------------------------------------------------------------------